Я пытаюсь вычесть 3 часа из метода, который я создал, но получаю ошибку - PullRequest
0 голосов
/ 04 октября 2018

Я успешно создал метод DST с именем dst_datechange, который принимает дату и анализируется с использованием Time.parse.Это выглядит так:

require 'time'
def dst_datechange(date)
  date = Time.parse(date.to_s) # if date.class.eql?(String)
  case
  when (date > Time.parse('March 11, 2018 2:00am')) && (date < 
Time.parse('November 4, 2018 2:00am'))
    date = Time.parse('November 4, 2018 2:00am')
    puts "the date rounded to november 4, 2018"
  when (date > Time.parse('November 4 2018, 2:00am')) && (date < 
Time.parse('March 10, 2:00am'))
    date = Time.parse('March 10, 2019 2:00am')
    puts "the date rounded to march 10 2019"
  when (date > Time.parse('March 10, 2019 2:00am')) && (date < 
Time.parse('November 3, 2019 2:00am'))
    date = Time.parse('November 3, 2019 2:00am')
  when (date > Time.parse('November 3, 2019 2:00am')) && (date < 
Time.parse('March 8, 2020 2:00am'))
    date = Time.parse('March 8, 2020 2:00am')
  when (date > Time.parse('March 8, 2020 2:00am')) && (date < 
Time.parse('November 1, 2020 2:00am'))
    date = Time.parse ('November 1, 2020 2:00am')
  else
    raise "The date #{date} does not match any dst date parameter"
  end
  date
  puts "the new DST date is #{date}"
end

, и мои «путы» отображают это ...

the date rounded to: november 4, 2018 
 the new DST date is now: 2018-11-04 02:00:00 -0600

Теперь, когда я получаю правильную дату, у меня есть шаг, который делает это dst_datechange и выполняет вычитание, однако я получаю сообщение об ошибке:

TypeError: no implicit conversion of Integer into Array

Я не уверен, что я делаю неправильно, но я знаю, что, скорее всего, это проблема форматирования, когда я пытаюсь вычестьобъект даты и времени только с объектом времени.Вот мой шаг ниже, где трассировка стека указывает на ошибку:

  date = (dst_datechange(Time.now) - (60*60*3))
  puts "the date is now adjusted 3 hours back from 2:00am:  #{date} "
end

Я не уверен, как отформатировать это (60 * 60 * 3), чтобы вычесть 3 часа из этой новой даты ноября 2018-11-04 02:00:00 -0600 ив основном откат до 2018-11-03 23:00:00 -0600

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

Ваш метод def dst_datechange (date) не возвращает дату, которую вы хотите, но вместо этого помещает вашу строку.

Когда вы вызываете это во второй части, dst_datechange (Time.now), этоне возвращает дату, но возвращает значение для последнего пута.

Попытайтесь снова вызвать 'date' после того, как ваш последний положит в свой метод dst_datechange:

when (date > Time.parse('March 8, 2020 2:00am')) && (date < Time.parse('November 1, 2020 2:00am'))
date = Time.parse ('November 1, 2020 2:00am')
  else
    raise "The date #{date} does not match any dst date parameter"
  end
  puts "the new DST date is #{date}"
  date
end
0 голосов
/ 05 октября 2018

С 2007 года в большинстве юрисдикций в Соединенных Штатах и ​​Канаде переход на летнее время («летнее время») начался в 2:00 во второе воскресенье марта и завершился в 2:00 в первое воскресенье ноября.В Мексике летнее время начинается в 2:00 утра в первое воскресенье апреля и заканчивается в 2:00 утра в последнее воскресенье октября.Опыт может быть разным в других частях света. 1

При наличии объекта Time (возможно, вычисляемого из строкового представления времени) ваш код возвращает второй Time объект, равныйдо момента, когда произойдет следующее изменение, с летнего времени на ЗППП или наоборот (т. е. в тех частях Соединенных Штатов и Канады, которые приняли летнее время).Нет необходимости жестко связывать эти даты.Вычисление может быть выполнено следующим образом.

require 'time'

def dst_datechange(time)
  year = time.year
  if time.dst?
    start_std(year)
  else
    year += 1 if time >= Time.new(year, 11)
    start_dst(year)
  end
end

def start_std(year)
  date = Date.new(year, 11)
  date += (7-date.wday) % 7
  Time.new(date.year, date.month, date.day, 2)
end

def start_dst(year)
  date = Date.new(year, 3, 8)
  date += (7-date.wday) % 7
  Time.new(date.year, date.month, date.day, 2)
end

['June 17, 2018 1:00pm', 'November 4, 2018 12:59am', 'November 4, 2018 1:00am',      
 'March 10, 2019 1:59am', 'March 10, 2019 2:00am'].
  each do |s|
    t = DateTime.strptime(s, '%B %e, %Y %l:%M%P').to_time
    t = Time.new(t.year, t.month, t.day, t.hour, t.min, t.sec)
    puts "#{s}: #{ dst_datechange(t) }"
  end
  June     17, 2018  1:00pm: 2018-11-04 02:00:00 -0800
  November  4, 2018 12:59am: 2018-11-04 02:00:00 -0800
  November  4, 2018  1:00am: 2019-03-10 03:00:00 -0700
  March    10, 2019  1:59am: 2019-03-10 03:00:00 -0700
  March    10, 2019  2:00am: 2019-11-03 02:00:00 -0800

Обратите внимание, что первый, второй и последний примеры возвращают время, час которого равен 2.Это на самом деле через час после того, как время изменилось.Два других примера возвращают час 3, то есть мгновение после изменения времени.Примечание:

Time.new(2019, 3, 10, 2)
  #=> 2019-03-10 03:00:00 -0700
Time.parse('March 10, 2019 2:00am')
  #=> 2019-03-10 03:00:00 -0700

В будущем диапазоны дат перехода на летнее время могут измениться (как они это делали в 2007 году), или DST может быть исключен в целом .Следовательно, в производственном коде было бы целесообразно рассмотреть эти возможности.Предполагая, что метод Time # dst? будет продолжать существовать, Time.new(year,6).dst? должен сообщить нам, если у нас все еще есть летнее время, и если это так, можно искать изо дня в день, чтобы увидеть, когда происходят изменения времени.

1. Источник

0 голосов
/ 04 октября 2018

Вам необходимо указать, что вы хотите вычесть часы.Попробуйте:

(Time.now - 3.hours).to_datetime

Или, если вы используете ActiveSupport, вы можете указать, что хотите три часа назад:

3.hours.ago
...