Daylight Saving Time start and end dates in Ruby/Rails
我正在开发一个Rails应用程序,在这个应用程序中,我需要找到给定特定偏移量或时区的夏令时开始和结束日期。
我基本上把从用户浏览器(
我知道
1 2 | > Time.new.isdst => true |
但是使用这个来查找夏令时的开始日期和结束日期会占用太多资源,而且我还必须为我所拥有的每个时区偏移量执行此操作。
我想知道一个更好的方法。
好吧,根据你所说的和@dhouty的回答:
您希望能够输入一个偏移量并获取一组日期,以了解是否存在DST偏移量。我建议以一个由两个日期时间对象组成的范围结束,因为它很容易用于Rails中的许多用途…
1 2 3 4 5 6 7 8 9 10 11 12 | require 'tzinfo' def make_dst_range(offset) if dst_end = ActiveSupport::TimeZone[offset].tzinfo.current_period.local_end dst_start = ActiveSupport::TimeZone[offset].tzinfo.current_period.local_start dst_range = dst_start..dst_end else dst_range = nil end end |
现在,您有了一种方法,它不仅可以通过ActiveSupport附带的糖进行补偿。你可以这样做:
1 2 3 4 5 6 7 8 9 10 11 | make_dst_range(-8) #=> Sun, 08 Mar 2015 03:00:00 +0000..Sun, 01 Nov 2015 02:00:00 +0000 make_dst_range('America/Detroit') #=> Sun, 08 Mar 2015 03:00:00 +0000..Sun, 01 Nov 2015 02:00:00 +0000 make_dst_range('America/Phoenix') #=> nil #returns nil because Phoenix does not observe DST my_range = make_dst_range(-8) #=> Sun, 08 Mar 2015 03:00:00 +0000..Sun, 01 Nov 2015 02:00:00 +0000 |
今天正好是8月29日,所以:
1 2 3 4 5 6 7 8 9 10 11 | my_range.cover?(Date.today) #=> true my_range.cover?(Date.today + 70) #=> false my_range.first #=> Sun, 08 Mar 2015 03:00:00 +0000 #note that this is a DateTime object. If you want to print it use: my_range.first.to_s #=>"2015-03-08T03:00:00+00:00" my_range.last.to_s #=>"2015-11-01T02:00:00+00:00" |
ActiveSupport为您提供各种显示功能:
1 2 3 4 5 6 | my_range.first.to_formatted_s(:short) #=>"08 Mar 03:00" my_range.first.to_formatted_s(:long) #=>"March 08, 2015 03:00" my_range.first.strftime('%B %d %Y') #=>"March 08 2015" |
正如您所看到的,只使用偏移量是完全可行的,但是正如我所说,偏移量并不能告诉您所有的事情,所以您可能希望获取它们的实际时区并将其存储为一个字符串,因为该方法会很高兴地接受该字符串并仍然为您提供日期范围。即使您只是在您的区域和他们的区域之间获取时间偏移量,也可以很容易地将其更正为UTC偏移量:
1 2 3 | my_offset = -8 their_offset = -3 utc_offset = my_offset + their_offset |
你可能要找的是
给定时区偏移量,您可以使用
1 | ActiveSupport::TimeZone[-8].tzinfo.current_period |
或者,如果您有时区名称,也可以使用
1 | ActiveSupport::TimeZone['America/Los_Angeles'].tzinfo.current_period |