【问题标题】:Number of days between two Time instances两个 Time 实例之间的天数
【发布时间】:2012-03-25 08:56:39
【问题描述】:

如何确定 Ruby 中两个 Time 实例之间的天数?

> earlyTime = Time.at(123)
> laterTime = Time.now
> time_difference = laterTime - earlyTime

我想确定time_difference 中的天数(我不担心天数。向上或向下舍入都可以)。

【问题讨论】:

  • 你关心夏令时吗?
  • 好问题。考虑夏令时和闰年并不重要,因为此计算只会向少数人提示电子邮件提醒。

标签: ruby date time


【解决方案1】:

in_days (Rails 6.1+)

Rails 6.1 引入了新的ActiveSupport::Duration 转换方法,例如in_secondsin_minutesin_hoursin_daysin_weeksin_monthsin_years

因此,现在,您的问题可以这样解决:

date_1 = Time.parse('2020-10-18 00:00:00 UTC')
date_2 = Time.parse('2020-08-13 03:35:38 UTC') 

(date_2 - date_1).seconds.in_days.to_i.abs
# => 65

这里是a link to the corresponding PR

【讨论】:

    【解决方案2】:

    这是一个适用于 DST 的简单答案:

    numDays = ((laterTime - earlyTime)/(24.0*60*60)).round

    60*60 是一小时的秒数 24.0 是一天中的小时数。这是一个浮动,因为有些日子比 24 小时多一点,有些则更少。因此,当我们除以一天中的秒数时,我们仍然有一个浮点数,并且 round 将四舍五入到 最接近的整数。

    因此,无论哪种方式,如果我们通过 DST,我们仍然会四舍五入到最近的一天。即使您处于某个奇怪的时区,该时区的 DST 变化超过一个小时。

    【讨论】:

      【解决方案3】:

      如果您不想估计并且想考虑夏令时,这些答案都不会真正起作用。 例如秋季时钟更改前的星期三上午 10 点和之后的星期三上午 10 点,它们之间的时间将是 1 周 1 小时。在春季,它将是 1 周减去 1 小时。 为了获得准确的时间,您可以使用以下代码

      def self.days_between_two_dates later_time, early_time
         days_between = (later_time.to_date-early_time.to_date).to_f
         later_time_time_of_day_in_seconds = later_time.hour*3600+later_time.min*60+later_time.sec
         earlier_time_time_of_day_in_seconds = early_time.hour*3600+early_time.min*60+early_time.sec
         days_between + (later_time_time_of_day_in_seconds - early_time_time_of_day_in_seconds)/1.0.day   
      end
      

      【讨论】:

        【解决方案4】:
        [1] pry(main)> earlyTime = Time.at(123)
        => 1970-01-01 01:02:03 +0100
        [2] pry(main)> laterTime = Time.now
        => 2014-04-15 11:13:40 +0200
        [3] pry(main)> (laterTime.to_date - earlyTime.to_date).to_i
        => 16175
        

        【讨论】:

          【解决方案5】:

          要考虑 DST(夏令时),您必须按天数计算。请注意,这假设少于一天被计为 1(四舍五入):

          num = 0
          cur = start_time
          while cur < end_time
            num += 1
            cur = cur.advance(:days => 1)
          end
          return num
          

          【讨论】:

          • 对于一般用途来说太慢了
          【解决方案6】:
          require 'date'
          days_between = (Date.parse(laterTime.to_s) - Date.parse(earlyTime.to_s)).round
          

          编辑 ...或更简单...

          require 'date'
          (laterTime.to_date - earlyTime.to_date).round
          

          【讨论】:

          • 字符串化时间只是为了立即解析它们对我来说似乎有点奇怪:)
          【解决方案7】:
          earlyTime = Time.at(123)
          laterTime = Time.now
          time_difference = laterTime - earlyTime
          time_difference_in_days = time_difference / 1.day  # just divide by 1.day
          

          【讨论】:

          • 对不起,您提到了 Ruby,但没有特别提到 Ruby on Rails。我认为您不会在 vanilla ruby​​ 中获得 1.day 功能。
          • 没错,你没有。除非您需要适当的 active_support 部分。
          【解决方案8】:

          两次的差以秒为单位。除以 24 小时内的秒数。

          (t1 - t2).to_i / (24 * 60 * 60)
          

          【讨论】:

          • @Tallboy 我所做的是将所有内容存储在UTC 中,并使用Timezone UTC 实例进行这些计算。在视图中渲染任何 Time 时,将适当显示夏令时。
          • @GonZifroni 所以在代码中添加 .utc ? (t1.utc - t2.utc) / (24*60*60) 或者如果使用(某些)rails 的 gem:(t1.utc-t2.utc)/1.days
          • 如果这是 Rails 你可以使用(t1 - t2).to_i / 1.day.seconds
          猜你喜欢
          • 2011-04-17
          • 1970-01-01
          • 1970-01-01
          • 2014-04-12
          • 1970-01-01
          • 2017-10-13
          • 1970-01-01
          • 1970-01-01
          • 2014-06-14
          相关资源
          最近更新 更多