-
Notifications
You must be signed in to change notification settings - Fork 149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: ZonedDateTime::round incorrect results with smallestUnit:day #2790
Comments
Actually, I've found a bug with the current algorithm: const zdt0 = Temporal.ZonedDateTime.from('2024-03-10T23:00:01[America/New_York]')
const zdt1 = zdt0.round({ smallestUnit: 'day', roundingMode: 'ceil' })
console.log(zdt1.toString()) // '2024-03-12T00:00:00-04:00[America/New_York]' It gets rounded up by 24 hours and 59 seconds, which is clearly wrong. This is happening because:
If the algorithm is trying to test how far the ZDT has progressed through all the nanoseconds of the current day, the location of the DST-gap within the 23-hour would need to be considered (in this example, it happens at 2am on the 10th). OR, in my opinion, we should simply round the wallclock-time, and then let the TimeZone massage it into an epochNanoseconds. The algorithm is simpler for this and its what most people would expect in my opinion. This would mean that 11:59 am rounded with a |
@ptomato and @justingrant I'll implement that fix we discussed in the meeting. I'll open a PR soon. |
Champions meeting 2024-02-29: All are agreed that is definitely a bug. So unfortunately that probably means queuing up another normative change for next plenary. |
The following code shows how ZonedDateTime would previously get rounded up by two days instead of the intended 1 day: const zdt0 = Temporal.ZonedDateTime.from('2024-03-10T23:00:01[America/New_York]') const zdt1 = zdt0.round({ smallestUnit: 'day', roundingMode: 'ceil' }) console.log(zdt1.toString()) // '2024-03-12T00:00:00-04:00[America/New_York]' - 23:00:01 is considered the numerator - 23:00:00 is considered the denominator (because 2024-03-10 has 23 hours in this tz) - Dividing results in a number slightly larger than 1 - The ceil func nudges it to 2 (i.e. 2 days from 2024-03-10T00:00:00) This is the spec text corresponding to the reference code change in the previous commit. Closes: tc39#2790
The following code shows how ZonedDateTime would previously get rounded up by two days instead of the intended 1 day: const zdt0 = Temporal.ZonedDateTime.from('2024-03-10T23:00:01[America/New_York]') const zdt1 = zdt0.round({ smallestUnit: 'day', roundingMode: 'ceil' }) console.log(zdt1.toString()) // '2024-03-12T00:00:00-04:00[America/New_York]' - 23:00:01 is considered the numerator - 23:00:00 is considered the denominator (because 2024-03-10 has 23 hours in this tz) - Dividing results in a number slightly larger than 1 - The ceil func nudges it to 2 (i.e. 2 days from 2024-03-10T00:00:00) This is the spec text corresponding to the reference code change in the previous commit. Closes: tc39#2790
Currently, the ZonedDateTime::round() methods operates like this:
getPossibleInstantsFor
calls)I don't understand why step 2 is necessary and why 24:00 can't be used for step 3. In step 4, the TimeZone will naturally nudge nonexistent times out of DST gaps anyway.
FWIW, temporal-polyfill skips those steps. All tests pass except those expecting more
getPossibleInstantsFor
calls.This would indicate to me that either: a) those steps can be eliminated or b) those steps are required but don't have test coverage.
Thank you for considering this ticket!
If you agree, I'd be happy to make a PR for both proposal-temporal and test262. I'd just like to validate my idea first.
The text was updated successfully, but these errors were encountered: