spencermountain / spacetime

A lightweight javascript timezone library
http://spacetime.how/
Other
3.99k stars 183 forks source link

isDST() Daylight Saving Date Range Incorrect #186

Closed alexkmerz closed 4 years ago

alexkmerz commented 4 years ago

I have found an issue with the isDST function, where it appears to be 1 day 'late'.

If I am correct, daylight savings in Pacific/Auckland should start at 2:00 AM on the last Sunday of September, and end at 3:00 AM on the first Sunday of April.

This would lead to the dates below for the start and end of daylight savings for the 2019-2020 period. Start: Sunday 29th September 2019 at 2:00 AM End: Sunday 5th April 2020 at 3:00 AM

From the code snippet below, it appears that the hour rollback is functioning at the correct date (at 29th of September the time gets rolled back an hour), however calling the isDST() function is returning false

(Another peculiar issue arose where for some reason setting the time to 3:01 AM was retaining it at 1:01 AM)

let dst = spacetime('2019-09-28', 'Pacific/Auckland');

for(let i = 0; i < 3; i++) {
    dst = dst.add(1, 'days');
    dst = dst.time('1:59AM');
    console.log(dst.format('nice') + " (" + dst.isDST() + ")");
    dst = dst.time('2:01AM');
    console.log(dst.format('nice') + " (" + dst.isDST() + ")");
    dst = dst.time('3:01AM');
    console.log(dst.format('nice') + " (" + dst.isDST() + ")");
}

Output:

Sept 29th, 1:59am (false) Sept 29th, 1:01am (false) Sept 29th, 1:01am (false) Sept 30th, 1:59am (true) Sept 30th, 2:01am (true) Sept 30th, 3:01am (true) Oct 1st, 1:59am (true) Oct 1st, 2:01am (true) Oct 1st, 3:01am (true)

spencermountain commented 4 years ago

thanks Alex, this is a good issue. yeah, no matter what, setting time to 2:01, should always be 2:01!

my guess is that this is related to #182 . Because we use native js objects, things get hairy within an hour of a DST change. I'm gonna put a big disclaimer for this on the readme.

this case seems more-solvable than the others, because we know what the result time should be. so it may be more solvable than 182 is.

i'll leave this here, for reference: spacetime('2019-09-29', 'Pacific/Auckland').time('2:01AM').format('time') cheers

alexkmerz commented 4 years ago

The biggest issue is the isDST() function returning false when it should be true, albeit I was trying to use this function to hotfix the previous issue #184

Cheers

spencermountain commented 4 years ago

hey Alex, I think this is fixed now, thanks for your patience. Note: the Auckland Dst date has changed since you reported this, and is now Sept 27th 2:00am:

let dst = spacetime('2019-09-25', 'Pacific/Auckland')

for (let i = 0; i < 3; i++) {
  dst = dst.add(1, 'days')
  dst = dst.time('1:59AM')
  console.log(dst.format('nice') + ' (' + dst.isDST() + ')')
  dst = dst.time('2:01AM')
  console.log(dst.format('nice') + ' (' + dst.isDST() + ')')
  dst = dst.time('3:01AM')
  console.log(dst.format('nice') + ' (' + dst.isDST() + ')')
}
/*
Sept 26th, 1:59am (false)
Sept 26th, 2:01am (false)
Sept 26th, 3:01am (false)
Sept 27th, 1:59am (false)
Sept 27th, 1:01am (false)
Sept 27th, 3:01am (true)
Sept 28th, 1:59am (true)
Sept 28th, 2:01am (true)
Sept 28th, 3:01am (true)
*/

plz let me know if i've messed it up thanks

Ahmed-Dghaies commented 1 year ago

Hi, i have exactly the same problem with "Europe/Paris"

spencermountain commented 1 year ago

hi @Ahmed-Dghaies can you reproduce this? This works for me cheers