Метод Ruby, который принимает текущую дату и, если она попадает между датами перехода на летнее время (DST), возвращает дату следующего изменения - PullRequest
0 голосов
/ 24 сентября 2018

Я пытаюсь написать метод, который принимает сегодняшнюю дату, и если указанная дата попадает между датами летнего времени на 2018 год (летнее время истинно, если дата 03/11/18 2:00 и 11/04/18 2:00 am), то будет возвращена дата следующего соответствующего изменения летнего времени.

На самом деле я понятия не имею, как к этому подойти, кроме как взять указанную дату и написать заявление о ней, повторяющее данный год для данной даты.и каждый, когда проходит другой год

# 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 голосов
/ 25 сентября 2018

Я истолковал вопрос следующим образом: «Если задана дата (возможно, сегодняшняя дата), если в этот день ни разу не наступило летнее время, верните 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_time , Time # dst? , Числовой # step и Enumerable # 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)>

Чтобы ускорить процесс, можно выполнить бинарный поиск, чтобы определить следующую дату изменения DST-non_DST, используя Range # bsearch .Я предположил, что летнее время заканчивается некоторое время до 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
...