Ruby方法采用今天的日期,如果它介于DST(夏令时)日期之间,则返回下一次更改的日期

时间:2018-09-24 15:46:48

标签: ruby date dst

我正在尝试编写一种方法,该方法采用今天的日期,并且提供的日期介于2018年的夏令时之间(如果日期为03/11/18 2:00 am和11/04/18 2:00 am,则DST为true ),那么它将返回下一个相应DST更改的日期。

除了采取提供的日期并围绕其写一个案例声明,然后反复遍历提供的给定年份,我实际上不知道该如何处理。并且每个时候拥有不同的年份

# method to take todays date and if the date falls in between DST dates, 
# then the method will return the date of the next DST change

def dst_date_change(date)
    return case 
        when date.include? ='2018'
            if (date > Time.parse('March 11, 2018 2:00am') &&  (date < Time.parse('November 4, 2018 2:00am'))
    end
        when date.include? ='2019'
            if 

    end
        when date.include? ='2020'
        if
    end
        when date.include? ='2020'
        if  
    end
    else 

这是我目前拥有的。显然未完成。.

1 个答案:

答案 0 :(得分:0)

我对问题的解释如下:“给定一个日期(可能是今天的日期),如果当天没有任何时间,则返回nil。否则,返回下一个日期(可能是同一日期) ),以DST开始,以非DST结尾”。

require 'date'

def next_dst_date_change(base_date)
  base_date_time = base_date.to_time
  next_date_time = (base_date+1).to_time
  if base_date_time.dst? || next_date_time.dst?
    base_date + 1.step.find { |n| (base_date + n).to_time.dst? == false } - 1
  end
end

请参见Date#to_timeTime#dst?Numeric#stepEnumerable#find

示例

d0 = Date.today
  #=> #<Date: 2018-09-24 ((2458386j,0s,0n),+0s,2299161j)>
next_dst_date_change(d0)
  #=> #<Date: 2018-11-04 ((2458427j,0s,0n),+0s,2299161j)>

d1 = Date.new(2018, 11, 04)
  #=> #<Date: 2018-11-04 ((2458427j,0s,0n),+0s,2299161j)>
next_dst_date_change(d0)
  #=> #<Date: 2018-11-04 ((2458427j,0s,0n),+0s,2299161j)>

d2 = d0 + 90
  #=> #<Date: 2018-12-23 ((2458476j,0s,0n),+0s,2299161j)>
next_dst_date_change(d2)
  #=> nil

d3 = d0 + 365
  #=> #<Date: 2019-09-24 ((2458751j,0s,0n),+0s,2299161j)>
next_dst_date_change(d3)
  #=> #<Date: 2019-11-03 ((2458791j,0s,0n),+0s,2299161j)>

d4 = Date.new(2018, 3, 10)
  #=> #<Date: 2018-03-10 ((2458188j,0s,0n),+0s,2299161j)>
next_dst_date_change(d4)
  #=> nil

d5 = Date.new(2018, 3, 11)
next_dst_date_change(d5)
  #=> #<Date: 2018-11-04 ((2458427j,0s,0n),+0s,2299161j)>

为了加快速度,可以使用Range#bsearch进行二进制搜索以确定下一个DST到non_DST的更改日期。我假设DST会在每年12月1日之前结束。

def next_dst_date_change(base_date)
  base_date_time = base_date.to_time
  next_date_time = (base_date+1).to_time
  if base_date_time.dst? || next_date_time.dst?
    diff = (Date.new(base_date.year, 12, 1) - base_date).to_i
    base_date + (1..diff).bsearch { |n| !(base_date + n).to_time.dst? } - 1
  end
end