date-fns-tz
date-fns-tz copied to clipboard
getTimezoneOffset off with one hour?
I've debugged my code for a long time, because my a particular test fails over and over again. The test case resolves around figuring out whether there is a switch in "DST mode" (winter to summer time, or vice versa) for a given time range (2 date objects) and a given time zone (which neither is UTC or client time zone). Here is the case:
For Europe/Oslo
, the following is true (winter to summer time):
Sunday, 27 March 2022, 02:00:00 clocks are turned forward 1 hour to....
Sunday, 27 March 2022, 03:00:00 local daylight time instead.
This can easily be checked with vanilla getTimezoneOffset (I'm using latest version of Chrome), when client is set to the Europe/Oslo
time zone:
d1 = new Date("2022-03-27T00:30:00.000Z");
// Sun Mar 27 2022 01:30:00 GMT+0100 (Central European Standard Time)
d2 = new Date("2022-03-27T01:30:00.000Z");
// Sun Mar 27 2022 03:30:00 GMT+0200 (Central European Summer Time)
d1.getTimezoneOffset();
// -60
d2.getTimezoneOffset()
//-120
Correspondingly, one should get the same result when using date-fns-tz getTimezoneOffset - but the result differs...
import { getTimezoneOffset } from "date-fns-tz";
d1 = new Date("2022-03-27T00:30:00.000Z");
// Sun Mar 27 2022 01:30:00 GMT+0100 (Central European Standard Time)
d2 = new Date("2022-03-27T01:30:00.000Z");
// Sun Mar 27 2022 03:30:00 GMT+0200 (Central European Summer Time)
getTimezoneOffset("Europe/Oslo", d1) / (-1 * 60 * 1000);
// -60
getTimezoneOffset("Europe/Oslo", d2) / (-1 * 60 * 1000);
// -60 <--- WRONG?!
However, if I try with one hour later, date-fns-tz getTimezoneOffset seems to get it right again...
import { getTimezoneOffset } from "date-fns-tz";
d3 = new Date("2022-03-27T02:30:00.000Z");
// Sun Mar 27 2022 04:30:00 GMT+0200 (Central European Summer Time)
getTimezoneOffset("Europe/Oslo", d3) / (-1 * 60 * 1000);
// -120
Could it be that date-fns-tz getTimezoneOffset is off with one hour?
FYI: Tested with both version 1.2.2
and 1.3.4
of date-fns-tz
(seems to be the same problem)
Unfortunately, I'm also facing similar issue getTimezoneOffset is not acting how it suppose to. It would be great someone you give a proper fix for this issue otherwise, I have to write some extra unnecessary code for overcoming this.
I might be wrong but it looks like(from the code and existing spec) that date is treated as date in the time zone (offset is ignored). With that logic applied - results that you get are expected.
@healqq : I'm not sure if I understand what you mean:
I might be wrong but it looks like(from the code and existing spec) that date is treated as date in the time zone (offset is ignored). With that logic applied - results that you get are expected.
I'd expect getTimezoneOffset not to ignore offset - it's the very essence of the function. And it's working for most cases, just not for the cases described by this bug report.
I'm having a similar issue, it seems to be specific for the DST boundaries, so for 2023 DST starts on March 23 02:00 EST, I have a simple test code for it
const { format, utcToZonedTime, getTimezoneOffset, zonedTimeToUtc } = require('date-fns-tz');
const timeZone = 'America/New_York';
const fn = (dateStr) => {
const dateFns = zonedTimeToUtc(dateStr, timeZone);
console.log(dateFns.toISOString());
console.log(getTimezoneOffset(timeZone, dateFns) / ((60000 * 60)));
}
fn('2023-03-12 01:00:00');
/**
* 2023-03-12T06:00:00.000Z
* -4
* Time is OK, but offset should be -5
*/
fn('2023-03-12 02:00:00');
/**
* 2023-03-12T06:00:00.000Z
* -4
* Time is off since 02:00 am do not exists since is when DST starts, so it should be 03:00 (07:00 UTC)
*/
fn('2023-03-12 03:00:00');
/**
* 2023-03-12T07:00:00.000Z
* -4
*
* This one is fine
*/
This one just came up for us. We took a timeZone name to display the offset GMT-04:00
kind of thing and didn't notice it until we provided America/Santiago
this week, before the timezone shift on 2020-09-11. So we're currently seeing GMT-03:00
, but we should be seeing GMT-04:00
until Sunday.
We've just been passing in the current date (new Date()) as the formatted date using the following code: formatInTimeZone(new Date(), 'America/Santiago', 'OOOO');
which should spit it out correctly, but alas its an hour off.
Has anyone come up with a workaround or fix for this?
Whilst I still struggle with TZ; I think the logic of the current tests are wrong: https://github.com/marnusw/date-fns-tz/blob/4ced7b8b0a5aad5b08fc3a44476242c82bc3272d/src/getTimezoneOffset/test.js#L53-L55
and
https://github.com/marnusw/date-fns-tz/blob/4ced7b8b0a5aad5b08fc3a44476242c82bc3272d/src/getTimezoneOffset/test.js#L58-L60
Seems to be checking that 'Australia/Melbourne' enter DST at 02:00 UTC but they actually do it at 02:00 local time. I believe the correct tests should be
var date = new Date('2020-10-04T01:45:00.000+10:00')
and var date = new Date('2020-10-04T03:15:00.000+11:00')
. This currently causes the tests to "fail" which I think implies the logic also needs changing?
This is exactly the bug, getTimezoneOffset
returns wrong value on DST change, for 1 hour.
In below example you can see that momentjs or native js methods returns correct value for the same timestamp.
I've found this bug on highcharts chart using offset to correctly display datetime string on xAxis. Dates were displayed incorrectly.