2

I am writing an automation test using two methods for daylight savings time purposes. These methods are defined as follows:

  • Adjust the inputted DATETIME (via Time.Parse) to round to the nearest DST change
  • Check to see that the method's DATETIME changed either one hour back or forward, whether the Time.Parse .include?("March") OR .include("November")

To reiterate, this method's purpose is to take the date from the previous method I wrote (that adjusts the current date and rounds it up to the next DST date), determine whether the return value is March or November, and VERIFIES that the time went forward or backward. The first method has been completed and is as follows:

def dst_datechange(date)
  date = Time.now
  case date
  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')
  when (date > Time.Parse('November 4 2018, 2:00am')) && (date < 
Time.parse('March 10, 2:00am'))
    date = Time.parse('March 10, 2019 2:00am')
  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
end

Now, my question is, how do I take the returned DATETIME value from that case statement, put it in an if statement to determine whether it includes a NOVEMBER or MARCH month, and then if it is march, then check to see if the time goes forward one hour or if its November, then check to see if the time goes back one hour.

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
AA.
  • 29
  • 6
  • You would be better off stating your question without reference to your method `dst_datechange` (whose argument, `date`, is not used, btw, as the value of `date` is overwritten in the first line). That is in part because that method could be written much more efficiently (without hardwiring the times when there are DST changes). More generally, when you state questions, avoid assuming that particular steps are required to answer them. – Cary Swoveland Oct 01 '18 at 00:49

1 Answers1

1

A few notes:

  • your date is actually a Time
  • you should remove the date in case date if your when are booleans. A time will never be a boolean so you will always get the else statement.
  • or you could leave date and replace when with a range of time. See here.

Your method is looking for the first dst change which is later than time. So you could use find on a list of times:

def next_time_change(time)
  next_change = [
    [2018, 3, 11],
    [2018, 11, 4],
    [2019, 3, 10],
    [2019, 11, 3],
    [2020, 3, 11],
    [2020, 11, 1]
  ].map do |year, month, day|
    Time.local(year, month, day, 2)
  end.find do |time_change|
    time < time_change
  end
  raise "The time #{time} does not match any dst date parameter" unless next_change
  next_change
end

puts next_time_change(Time.now)
# => 2018-11-04 02:00:00 +0100

puts next_time_change(Time.local(2030, 1, 1))
# dst_change.rb:14:in `next_time_change': The time 2030-01-01 00:00:00 +0100 does not match any dst date parameter (RuntimeError)
#   from dst_change.rb:21:in `<main>'
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • So, is this basically a combination of the two methods I was needing? Sorry I am still new to programming and trying to gather my thoughts. This method takes this years and future DST dates, puts them in an array. the .map do parses them out to a y/m/d format. then the find will take the results and set them in a time change method that returns whether the inputted date is before the nex time change. and if it matches the it, then it returns the net change. correct...? – AA. Oct 02 '18 at 15:02
  • @AA.: Yes. For a given `time`, it finds the next time at which DST will change (either in march or november). The array input is just to avoid the many `Time.parse`. By the way, you might be interested in https://stackoverflow.com/questions/29494206/ruby-getting-the-next-daylight-savings-change – Eric Duminil Oct 02 '18 at 16:21
  • with regards to that link, I actually pressed to use ruby's built in .dst method cuz I figured it works and it would save a lot of time, but from what i understand, it was incorrect and we had to write out our own method to determine if a current date was a dst date. That was last march that this was an issue, however. I havent revisited it since I was told not to mess with the .dst method – AA. Oct 02 '18 at 16:51
  • Also, I am getting an ArgumentError: comparison of STring with Time failed. Im passing in 2018, 10, 2 into my cucumber feature parameters (and the provided 2 in the method assumes the time I think.) im only passing in numbers so I dont know why i am getting a string comparison error? – AA. Oct 02 '18 at 17:38