夏令时开始和结束日期在Ruby / Rails中 [英] Daylight Saving Time start and end dates in Ruby/Rails

查看:79
本文介绍了夏令时开始和结束日期在Ruby / Rails中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Rails应用,需要在给定特定偏移量或时区的情况下找到夏令时的开始和结束日期。

I'm working on a Rails app where I need to find the Daylight Saving Time start and end dates given a specific offset or timezone.

我基本上将从用户浏览器收到的时区偏移量保存在数据库中( + 3 -5 ),我想在由于夏令时而更改它时对其进行修改。

I basically save in my database the timezone offset received from a user's browser( "+3", "-5") and I want to modify it when it changes because of daylight saving time.

我知道 Time 实例变量具有 dst? isdst 方法,它们返回true如果存储在其中的日期是否在夏时制中,则返回false。

I know Time instance variables have the dst? and isdst methods which return true or false if the date stored in them is in the daylight saving time or not.

 > Time.new.isdst
 => true 

但是使用此方法来查找夏令时的开始和结束日期会占用太多资源,

But using this to find the Daylight Saving Time beginning and end dates would take too many resources and I also have to do it for each timezone offset I have.

我想知道一种更好的方法。

I would like to know a better way of doing this.

推荐答案

好,请根据您所说的内容和 @dhouty的答案

Ok, building on what you've said and @dhouty's answer:

您希望能够输入偏移量并获得一组日期,以了解是否存在DST偏移量。我建议以一个由两个DateTime对象组成的范围作为结束,因为在Rails中很容易将其用于许多用途...

You want to be able to feed in an offset and get a set of dates for knowing if there is a DST offset or not. I would recommend ending up with a range made of two DateTime objects, as that is easily used for many purposes in 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附带的糖,您有一种方法可以做的不仅仅是抵消。您可以执行以下操作:

Now you have a method that can do more than just take an offset thanks to the sugar that comes with ActiveSupport. You can do things like:

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日,所以:

Today happens to be August 29th so:

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为您提供各种支持显示的好东西:

ActiveSupport gives you all sorts of goodies for display:

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并不能告诉您所有信息,因此您可能希望获取其实际时区并将其存储为字符串,因为该方法将很乐意接受该字符串并仍然为您提供日期范围。即使您只是获得区域与区域之间的时间偏移,也可以轻松地将其校正为UTC偏移:

As you can see it's completely doable with just the offset, but as I said, offset doesn't tell you everything, so you might want to grab their actual time zone and store that as a string since the method will happily accept that string and still give you the date range. Even if you are just getting the time offset between your zone and theirs, you can easily figure correct that to the UTC offset:

my_offset = -8
their_offset = -3
utc_offset = my_offset + their_offset

这篇关于夏令时开始和结束日期在Ruby / Rails中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆