spencermountain / spacetime

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

Unexpected results near DST 2023 boundaries (Europe/Helsinki) #374

Closed pulakkam closed 1 year ago

pulakkam commented 1 year ago

Hello,

I checked if there are any problems related to DST 2023 in Europe/Helsinki and there seem to be some.

My test code:

import spacetime from 'spacetime'

const isotimes = [
  '2023-03-26T00:30:00.000Z', // March 2023
  '2023-03-26T01:30:00.000Z',
  '2023-03-26T02:30:00.000Z',
  '2023-03-26T03:30:00.000Z',
  '2023-03-26T04:30:00.000Z',
  '2023-03-26T05:30:00.000Z',
  '2023-10-29T00:30:00.000Z', // October 2023
  '2023-10-29T01:30:00.000Z',
  '2023-10-29T02:30:00.000Z',
  '2023-10-29T03:30:00.000Z',
  '2023-10-29T04:30:00.000Z',
]

isotimes.forEach((isotime) => {
  const time = spacetime(isotime)
  console.log(isotime)
  console.log(time.format('iso'))
  console.log(time.goto('Europe/Helsinki').format('iso'))
  console.log()
})

Results:

2023-03-26T00:30:00.000Z
2023-03-26T00:30:00.000Z
2023-03-26T02:30:00.000+02:00

2023-03-26T01:30:00.000Z
2023-03-26T01:30:00.000Z
2023-03-26T05:30:00.000+03:00 // Expected: 2023-03-26T04:30:00.000+03:00

2023-03-26T02:30:00.000Z
2023-03-26T02:30:00.000Z
2023-03-26T06:30:00.000+03:00 // Expected: 2023-03-26T05:30:00.000+03:00

2023-03-26T03:30:00.000Z
2023-03-26T02:30:00.000Z      // Expected: 2023-03-26T03:30:00.000Z
2023-03-26T06:30:00.000+03:00

2023-03-26T04:30:00.000Z
2023-03-26T04:30:00.000Z
2023-03-26T07:30:00.000+03:00

2023-03-26T05:30:00.000Z
2023-03-26T05:30:00.000Z
2023-03-26T08:30:00.000+03:00

2023-10-29T00:30:00.000Z
2023-10-29T00:30:00.000Z
2023-10-29T03:30:00.000+03:00

2023-10-29T01:30:00.000Z
2023-10-29T00:30:00.000Z      // Expected: 2023-10-29T01:30:00.000Z
2023-10-29T03:30:00.000+03:00

2023-10-29T02:30:00.000Z
2023-10-29T02:30:00.000Z
2023-10-29T03:30:00.000+02:00 // Expected: 2023-10-29T04:30:00.000+02:00

2023-10-29T03:30:00.000Z
2023-10-29T03:30:00.000Z
2023-10-29T05:30:00.000+02:00

2023-10-29T04:30:00.000Z
2023-10-29T04:30:00.000Z
2023-10-29T06:30:00.000+02:00

Is there something I could do to get expected results?

Thank you.

spencermountain commented 1 year ago

hey Matti - thank you for the good bug. I think i know what is happening, and it is crazy.

There's some ambiguity when parsing a iso timezone. We get '+05:30' and we try to match it to the most appropriate iana code. We let users clear this up with spacetime(iso, tz). There are cases when those two timezones don't line up - and we flail around trying to guess timezones.

I think that's what's happening here.

can you confirm that this produces the correct results?

isotimes.forEach((isotime) => {
  const time = spacetime(isotime, 'ETC/UTC')
  console.log(isotime)
  console.log(time.format('iso'))
  console.log(time.goto('Europe/Helsinki').format('iso'))
  console.log()
})

This is pretty dirty. I'll need to think about what the best way to address this is. let me know if that clears it up cheers

pulakkam commented 1 year ago

Actually the results are identical, no difference between my original code and your version.

spencermountain commented 1 year ago

oof, sorry! lemme check it out after a good sleep.

spencermountain commented 1 year ago

oh - yup, this is a dupe of #235 sorry for my code-blindness yeterday i'm working on a fix. it requires a re-write. Hope to have it ready in a couple weeks, atleast as a beta thanks for your patience. the offsets will only be off by an hour, within an hour of a dst change cheers