【问题标题】:Should ActiveSupport::TimeWithZone (and Time.zone)'s methods respect DST changes?ActiveSupport::TimeWithZone(和 Time.zone)的方法是否应该尊重 DST 更改?
【发布时间】:2014-11-05 10:52:43
【问题描述】:

看看这段代码:

[4, 5, 6, 7].each do |x| 
  start_at = Time.zone.parse("2014.10.2#{x} 08:00")
  puts "#{start_at.inspect} / #{start_at.seconds_since_midnight/60}"
end

输出:

Fri, 24 Oct 2014 08:00:00 CEST +02:00 / 480.0
Sat, 25 Oct 2014 08:00:00 CEST +02:00 / 480.0
Sun, 26 Oct 2014 08:00:00 CET +01:00 / 480.0
Mon, 27 Oct 2014 08:00:00 CET +01:00 / 480.0

我们在德国,10 月 26 日 DST 被重置,因此 08:00 实际上不是午夜后的 8*60 分钟,而是 9*60。

恕我直言,seconds_since_midnight 方法应该尊重这一点。我错过了什么还是这实际上是一个 Ruby 错误?

在 Mac OS X 10.9.5 (MacPorts) 上使用 Ruby 1.9.3、Rails 3.0.20。

(是的,Rails 3.0.20 很旧。遗留项目。如果它在 Rails 4 中得到修复,那就更好了。)

【问题讨论】:

  • Matt 已经告诉了你原因,但很容易得到正确答案 - start_at - start_at.midnight

标签: ruby-on-rails ruby time timezone


【解决方案1】:

根据the Rails docs,是这样实现的:

# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 14
def seconds_since_midnight
  sec + (min * 60) + (hour * 3600)
end

因此,此功能不支持时区。它只是查看本地时间值。它不认为午夜的偏移量可能与您提供的值的偏移量不同。它也不认为本地时区可能不存在午夜(例如巴西的春季过渡)。

这是一个错误吗?也许。但也有人可能会说这种方法命名不当。无论哪种方式,这都是 Rails 的问题,而不是 Ruby。

【讨论】:

  • Rails 错误,而不是 Ruby 错误。正确的。我也查看了实现,但无法弄清楚时区校正是否可能在其他地方进行。时区是一个复杂的野兽。感谢您的澄清。 :)
  • 作为一般建议,请考虑不要使用 Rails 来支持时区。尽可能使用纯 Ruby 代码,并将 TZInfo gem 用于时区。有关详细信息,请参阅the timezone tag wiki 底部的 Rails 部分。
猜你喜欢
  • 1970-01-01
  • 2011-11-22
  • 1970-01-01
  • 2012-06-28
  • 2011-05-28
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多