夏令时开始和结束日期在Ruby / Rails中
我正在开发一个Rails应用程序,在那里我需要找到夏令时开始和结束日期,给定一个特定的偏移或时区。
我基本上在我的数据库中保存从用户浏览器接收到的时区偏移量( "+3"
, "-5"
),我想在夏令时发生变化时对其进行修改。
我知道Time
实例变量有dst?
以及isdst
方法,如果存储在其中的日期处于夏时制时间内,则该方法返回true或false。
> Time.new.isdst
=> true
但是,使用它来查找夏令时开始和结束日期将需要太多的资源,而且我也必须为每个时区偏移量执行此操作。
我想知道更好的方法来做到这一点。
好的,根据你所说的话和@ dhouty的回答:
您希望能够输入偏移量并获取一组日期以了解是否存在DST偏移量。 我会建议结束由两个DateTime对象组成的范围,因为这很容易用于Rails的许多目的...
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附带的糖而带来的偏移量。 你可以做这样的事情:
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日,所以:
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为您提供各种可用于展示的好东西:
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"
正如你所看到的,它完全可以用offset来实现,但正如我所说的,offset不会告诉你所有的东西,所以你可能想要抓住它们的实际时区并将它作为一个字符串存储,因为该方法会愉快地接受该字符串,并且仍然给你日期范围。 即使您刚刚获得您的区域和他们的区域之间的时间偏移,也可以很容易地根据UTC偏移量进行计算:
my_offset = -8
their_offset = -3
utc_offset = my_offset + their_offset
你可能在寻找的是TZInfo::TimezonePeriod
。 具体来说,方法local_start
/ utc_start
和local_end
/ utc_end
。
给定一个时区偏移量,你可以得到一个TZInfo::TimezonePeriod
对象
ActiveSupport::TimeZone[-8].tzinfo.current_period
或者,如果您TZInfo::TimezonePeriod
区名称,则也可以使用TZInfo::TimezonePeriod
对象
ActiveSupport::TimeZone['America/Los_Angeles'].tzinfo.current_period
链接地址: http://www.djcxy.com/p/29413.html