【问题标题】:How to check if variable is Date or Time or DateTime in Ruby?如何检查变量是否是 Ruby 中的日期或时间或日期时间?
【发布时间】:2016-10-24 21:47:55
【问题描述】:

有什么简单的方法可以检查变量/对象是否为Date / Time / DateTime 类型?没有命名所有类型

【问题讨论】:

  • 为什么要查?其中一些共享方法,让您在不知道它是什么类型的情况下使用它们?
  • 我有一个 Rails 活动记录,它有 2 个时间属性,我需要做一个 .map 来将每个时间属性转换为日期时间。将来可以在数据库中更改时间类型会很棒,因此问题..但我想我现在只是有点好奇......
  • 好奇为什么投反对票? ..有没有办法问那些投反对票的人?我一定在这个forum中激怒了某些人
  • 不,你不能问为什么有人投反对票...不要让它影响到你,很多时候人们也投反对票,我很困惑。你问了一个简单的问题,直截了当......不喜欢这种风格的人(即他们想要一个你刚刚问你的问题的理由。没有必要的 IMO)可能会否决它。但正如其他人所指出的那样,. instance_of?.class 可能是在 Ruby 中查找对象类的最佳解决方案。 GL 与你的工作!

标签: ruby-on-rails ruby date time


【解决方案1】:

另一种选择:

def is_datetime(d)
  d.methods.include? :strftime
end

或者:

if d.respond_to?(:strftime)
  # d is a Date or DateTime object
end 

【讨论】:

  • 感谢您的回答。它让我找到了这个解决方案:d.respond_to?(:strftime)
【解决方案2】:

你可以检查一个对象的类

object.class

它应该返回 Date、String 或任何它。你也可以反过来检查一个对象是否是一个类的实例:

object.instance_of?(class)

类是你要检查的(字符串,日期),返回真/假

【讨论】:

    【解决方案3】:

    如果你想验证对象,这里有几个例子:

    nisevi@nisevi ~:$ irb
    irb(main):001:0> require "date"
    => true
    irb(main):002:0> require "time"
    => true
    irb(main):003:0> d = Date.new
    => #<Date: -4712-01-01 ((0j,0s,0n),+0s,2299161j)>
    irb(main):004:0> dt = DateTime.new
    => #<DateTime: -4712-01-01T00:00:00+00:00 ((0j,0s,0n),+0s,2299161j)>  
    irb(main):005:0> t = Time.new
    => 2016-06-22 21:33:09 +0200
    
    irb(main):014:0> d.instance_of?(Date)
    => true
    irb(main):015:0> d.instance_of?(DateTime)
    => false
    irb(main):016:0> d.instance_of?(Time)
    => false
    irb(main):017:0> dt.instance_of?(DateTime)
    => true
    irb(main):018:0> dt.instance_of?(Time)
    => false
    irb(main):019:0> dt.instance_of?(Date)
    => false
    irb(main):020:0> t.instance_of?(Time)
    => true
    irb(main):021:0> t.instance_of?(DateTime)
    => false
    irb(main):022:0> t.instance_of?(Date)
    => false
    

    我还认为 TimeZone 来自 Rails 而不是来自 Ruby。

    根据您的评论,如果您想将 Time 对象转换为 DateTime,我认为这样的东西应该可以工作:

    def time_to_datetime time
      return time.to_datetime if time.instance_of?(Time)
      false
    end
    

    这里有一些代码:

    irb(main):026:0> t.instance_of?(Time)
    => true
    irb(main):027:0> t.methods.sort.to_s
    => "[:!, :!=, :!~, :+, :-, :<, :<=, :<=>, :==, :===, :=~, :>, :>=, :__id__, :__send__, :asctime, :between?, :class, :clone, :ctime, :day, :define_singleton_method, :display, :dst?, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :friday?, :frozen?, :getgm, :getlocal, :getutc, :gmt?, :gmt_offset, :gmtime, :gmtoff, :hash, :hour, :httpdate, :inspect, :instance_eval, :instance_exec, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :isdst, :iso8601, :itself, :kind_of?, :localtime, :mday, :method, :methods, :min, :mon, :monday?, :month, :nil?, :nsec, :object_id, :private_methods, :protected_methods, :public_method, :public_methods, :public_send, :remove_instance_variable, :respond_to?, :rfc2822, :rfc822, :round, :saturday?, :sec, :send, :singleton_class, :singleton_method, :singleton_methods, :strftime, :subsec, :succ, :sunday?, :taint, :tainted?, :tap, :thursday?, :to_a, :to_date, :to_datetime, :to_enum, :to_f, :to_i, :to_r, :to_s, :to_time, :trust, :tuesday?, :tv_nsec, :tv_sec, :tv_usec, :untaint, :untrust, :untrusted?, :usec, :utc, :utc?, :utc_offset, :wday, :wednesday?, :xmlschema, :yday, :year, :zone]"
    irb(main):028:0> t.to_datetime
    => #<DateTime: 2016-06-22T21:33:09+02:00 ((2457562j,70389s,767750206n),+7200s,2299161j)>
    irb(main):029:0> t.instance_of?(Time)
    => true
    irb(main):030:0> t.instance_of?(DateTime)
    => false
    irb(main):031:0> tdt = t.to_datetime
    => #<DateTime: 2016-06-22T21:33:09+02:00 ((2457562j,70389s,767750206n),+7200s,2299161j)>
    irb(main):032:0> tdt.instance_of?(Time)
    => false
    irb(main):033:0> tdt.instance_of?(DateTime)
    => true
    

    这里有一些有趣的信息In Ruby on Rails, what's the difference between DateTime, Timestamp, Time and Date?

    【讨论】:

      【解决方案4】:

      在 rails 5.2+ 你可以测试一个对象 is_a?

      Date.today.is_a?(Date) # -> true
      Date.today.is_a?(DateTime) # -> false
      

      【讨论】:

        【解决方案5】:

        我不认为有一个“简单的方法”不输入Date / Time / DateTime / Timezone 的所有类型变体。

        最简单、最快的方法是执行dateTime.is_a?(DateTime)Time.is_a?(Time)repeat ad nausem - 它们都将返回一个布尔值。

        反过来你也可以使用kind_of?.

        您也许还可以找到一个框架,该框架具有检查所有日期和时间变化的功能。

        【讨论】:

          【解决方案6】:

          要查找模块(或方法)所在的类,您可以使用.class 函数,这允许您检查 Ruby 对象以找出它们所在的类。语法如下所示: object.class。下面是一些例子:

          irb(main):001:0> require 'date'
          => true
          irb(main):002:0> d = Date.today
          => #<Date: 2016-06-22 ((2457562j,0s,0n),+0s,2299161j)>
          irb(main):003:0> t = Time.now
          => 2016-06-22 18:52:24 -0500
          irb(main):004:0> t.class
          => Time
          irb(main):005:0> d.class
          => Date
          

          如您所见,这是一种查找对象所在类的简单方法。

          【讨论】:

            【解决方案7】:

            columns和columns_hash返回的Column对象可以用来获取数据类型和默认值等信息,例如:

            User.columns_hash['email'].type
            => :string
            User.columns_hash['email'].default
            => nil
            User.columns_hash['email'].sql_type
            => "varchar(255)"
            

            (Source)

            【讨论】:

              【解决方案8】:

              为了完整起见,另一种选择是:

              def responds_to_datetime?(date)
                true if date.to_datetime rescue false
              end
              

              【讨论】:

                【解决方案9】:

                在 Rails 中,您可以使用 acts_like? 方法。时间不act_like_date?,所以你需要检查日期和时间。

                var.acts_like?(:date) || var.acts_like?(:time)
                

                【讨论】:

                  猜你喜欢
                  • 2020-03-08
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-07-26
                  • 2013-06-25
                  • 1970-01-01
                  • 2018-06-06
                  • 2012-05-27
                  • 2011-02-19
                  相关资源
                  最近更新 更多