【问题标题】:I am trying to subtract 3 hours from a method that I have created but I am getting an error我正在尝试从我创建的方法中减去 3 小时,但出现错误
【发布时间】:2019-03-10 00:22:02
【问题描述】:

我已经成功创建了一个名为 dst_datechange 的 DST 方法,该方法需要一个日期,并使用 Time.parse 进行解析。它看起来像这样:

require 'time'
def dst_datechange(date)
  date = Time.parse(date.to_s) # if date.class.eql?(String)
  case
  when (date > Time.parse('March 11, 2018 2:00am')) && (date < 
Time.parse('November 4, 2018 2:00am'))
    date = Time.parse('November 4, 2018 2:00am')
    puts "the date rounded to november 4, 2018"
  when (date > Time.parse('November 4 2018, 2:00am')) && (date < 
Time.parse('March 10, 2:00am'))
    date = Time.parse('March 10, 2019 2:00am')
    puts "the date rounded to march 10 2019"
  when (date > Time.parse('March 10, 2019 2:00am')) && (date < 
Time.parse('November 3, 2019 2:00am'))
    date = Time.parse('November 3, 2019 2:00am')
  when (date > Time.parse('November 3, 2019 2:00am')) && (date < 
Time.parse('March 8, 2020 2:00am'))
    date = Time.parse('March 8, 2020 2:00am')
  when (date > Time.parse('March 8, 2020 2:00am')) && (date < 
Time.parse('November 1, 2020 2:00am'))
    date = Time.parse ('November 1, 2020 2:00am')
  else
    raise "The date #{date} does not match any dst date parameter"
  end
  date
  puts "the new DST date is #{date}"
end

我的“puts”显示了这个......

the date rounded to: november 4, 2018 
 the new DST date is now: 2018-11-04 02:00:00 -0600

现在我收到了正确的日期,我有一个步骤可以采用 dst_datechange 并执行减法,但是,我收到一条错误消息:

TypeError: no implicit conversion of Integer into Array

我不确定我做错了什么,但我知道这很可能是一个格式问题,我试图用一个时间对象减去一个日期时间对象。这是我下面的步骤,堆栈跟踪将失败指向:

  date = (dst_datechange(Time.now) - (60*60*3))
  puts "the date is now adjusted 3 hours back from 2:00am:  #{date} "
end

我不确定如何格式化 (60*60*3) 以从新的 11 月 2018-11-04 02:00:00 -0600 日期减去 3 小时,然后基本上将其回滚到 2018-11-03 23:00:00 -0600

【问题讨论】:

  • 如果您遇到包含您创建的方法的错误,则包含该方法可能有意义。我们甚至无法在没有看到它的情况下调试您的代码。
  • 好的,刚刚添加了!

标签: ruby date datetime time dst


【解决方案1】:

您需要指定要减去小时数。试试:

(Time.now - 3.hours).to_datetime

或者,如果使用 ActiveSupport,您可以指定三小时前:

3.hours.ago

【讨论】:

  • 纯 Ruby 没有方法 Integer.hours。您需要将3.hours 替换为3*60*60
【解决方案2】:

您的方法 def dst_datechange(date) 不会返回您想要的日期,而是放置您的字符串。

当您在第二部分中调用它时,dst_datechange(Time.now),它不会返回日期,而是最后一次放置的返回值。

在您最后放入 dst_datechange 方法后再次尝试调用“日期”:

when (date > Time.parse('March 8, 2020 2:00am')) && (date < Time.parse('November 1, 2020 2:00am'))
date = Time.parse ('November 1, 2020 2:00am')
  else
    raise "The date #{date} does not match any dst date parameter"
  end
  puts "the new DST date is #{date}"
  date
end

【讨论】:

  • 那么,在我的案例末尾删除“日期”返回值,而是将其放入其中一个案例中?
  • @AA。不,返回日期之后 puts。 Ruby 有隐式返回:方法中最后的就是返回的。
  • 不管我这样做,我只是运行它,我仍然得到同样的错误......
  • 我并不完全需要puts,因为我知道该方法工作正常,这是成功的一半。我只需要计算工作
  • 然后在你的 dst_datechange 方法中确保你的最终“结束”之前的最后一个命令是“日期”
【解决方案3】:

自 2007 年以来,在美国和加拿大的大多数司法管辖区,夏令时 (“DST”) 从 3 月第二个星期日凌晨 2:00 开始,到 11 月第一个星期日凌晨 2:00 结束。在墨西哥,夏令时从四月的第一个星期日凌晨 2:00 开始,到十月最后一个星期日的凌晨 2:00 结束。世界其他地区的体验各不相同。1

给定一个 Time 对象(可能从时间的字符串表示计算),您的代码返回第二个 Time 对象,该对象等于下一次时间更改发生的时间,从 DST 到 STD,反之亦然(即,在已采用 DST 的美国和加拿大的那些地区)。无需硬连线这些日期。计算如下。

require 'time'

def dst_datechange(time)
  year = time.year
  if time.dst?
    start_std(year)
  else
    year += 1 if time >= Time.new(year, 11)
    start_dst(year)
  end
end

def start_std(year)
  date = Date.new(year, 11)
  date += (7-date.wday) % 7
  Time.new(date.year, date.month, date.day, 2)
end

def start_dst(year)
  date = Date.new(year, 3, 8)
  date += (7-date.wday) % 7
  Time.new(date.year, date.month, date.day, 2)
end

['June 17, 2018 1:00pm', 'November 4, 2018 12:59am', 'November 4, 2018 1:00am',      
 'March 10, 2019 1:59am', 'March 10, 2019 2:00am'].
  each do |s|
    t = DateTime.strptime(s, '%B %e, %Y %l:%M%P').to_time
    t = Time.new(t.year, t.month, t.day, t.hour, t.min, t.sec)
    puts "#{s}: #{ dst_datechange(t) }"
  end
  June     17, 2018  1:00pm: 2018-11-04 02:00:00 -0800
  November  4, 2018 12:59am: 2018-11-04 02:00:00 -0800
  November  4, 2018  1:00am: 2019-03-10 03:00:00 -0700
  March    10, 2019  1:59am: 2019-03-10 03:00:00 -0700
  March    10, 2019  2:00am: 2019-11-03 02:00:00 -0800

请注意,第一个、第二个和最后一个示例返回的时间为 2。这实际上是时间更改后的一小时。其他两个示例返回一个小时的3,这是时间更改后的一瞬间。注意:

Time.new(2019, 3, 10, 2)
  #=> 2019-03-10 03:00:00 -0700
Time.parse('March 10, 2019 2:00am')
  #=> 2019-03-10 03:00:00 -0700

将来,DST 日期范围可能会发生变化(就像 2007 年那样),或者 DST 可能是 eliminated altogether。因此,在生产代码中,解决这些可能性是谨慎的。假设Time#dst? 方法会继续存在,Time.new(year,6).dst? 应该会告诉我们是否还有夏令时,如果有,可以逐日搜索以查看时间更改的时间。

1. Source

【讨论】:

    猜你喜欢
    • 2014-07-26
    • 2021-04-30
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 2020-10-29
    • 1970-01-01
    相关资源
    最近更新 更多