marnusw / date-fns-tz

Complementary library for date-fns v2 adding IANA time zone support
MIT License
1.05k stars 114 forks source link

utcToZonedTime returns diffrent result in different timezone #75

Closed abhishek-personatech closed 2 years ago

abhishek-personatech commented 4 years ago

utcToZonedTime is not returning expected value in different timezone

Example:

System Timezone: "Los Angeles, CA - United States"

utcToZonedTime("2014-06-25T10:00:00.000Z", "America/New_York");

Output: "2014-06-25T13:00:00.000Z"

System Timezone: "Mumbai - India"

utcToZonedTime("2014-06-25T10:00:00.000Z", "America/New_York");

Output: "2014-06-25T00:30:00.000Z"

Why is it taking system timezone in calculation, when date is passed in UTC?

gretzky commented 3 years ago

@luludan @marnusw I'm still seeing this issue, utcToZonedTime outputs the first argument passed (the UTC date).


utcToZonedTime("2020-10-20T15:52:49.411Z", "America/New_York");

// outputs the same date in UTC, 15:52
// should output 11:52

It does work correctly when using it with `format`, just not standalone.
itneste commented 3 years ago

@luludan @marnusw I'm still seeing this issue, utcToZonedTime outputs the first argument passed (the UTC date).

utcToZonedTime("2020-10-20T15:52:49.411Z", "America/New_York");

// outputs the same date in UTC, 15:52
// should output 11:52

It does work correctly when using it with `format`, just not standalone.

yes,same issue~

xdumaine commented 3 years ago

I think this may have been fixed by https://github.com/marnusw/date-fns-tz/commit/e97b76c41a772342149394f0cbe8b9a0042c553f

ellis commented 3 years ago

Here's another example that highlights the problem. utcToZonedTime even gives the wrong result when requesting the "UTC" timezone (if your system isn't set to UTC). For example, from Europe/Berlin:

> utcToZonedTime("2021-01-01T00:00:00.000Z", "UTC")
2020-12-31T23:00:00.000Z

Using version 1.1.4.

Stevemoretz commented 3 years ago

Same issue does not work at all.

ankit-gaur commented 3 years ago

This is not a issue, it's how date-fns-tz work.

@marnusw IMHO we should put this in the documentation as most of the issues on this repository are because of mis-understanding.

Explaining conversion where system timezone is 'Mumbai India' :

utcToZonedTime("2014-06-25T10:00:00.000Z", "America/New_York");

Output: "2014-06-25T00:30:00.000Z"

utcToZonedTime method returns Date object with epoch number (internal value stored by the Date object) such that when that number is converted to system's timezone the values of y,m,d,h,m,s are what would have been in 'America/New York' timezone.

Output: "2014-06-25T00:30:00.000Z" when converted to Date object {new Date("2014-06-25T00:30:00.000Z")} on an Indian System will have hour value as 6 and minute value as 0 i.e. 6AM 25th june (Expected output for New York timezone)

Conclusion: iso values of output date object from utcToZonedTime method are meaningless and shouldn't be used, e.g. date.hour() will give you expected hour in the input timezone but date.isoHour() will just have some value which when adjusted for system's timezone will yield date.hour() as what is expected hour value in the input timezone if you need output in ISO string after conversion then you need to convert it once again with zonedTimeToUTC method.

marnusw commented 3 years ago

Thanks @ankit-gaur, you are correct.

Everyone note that taking the UTC time of the output date is useless. The point of the function is to have a date which you can pass to date-fns(-tz)#format the get the correct output, or pass this to a date picker or other component which will show the local time of the Date and not the UTC time.

In the latter case, once a user picks a new date this should be passed to zonedTimeToUtc and then you take the ISO string of the result to send back to the server.

As an example, assuming @ellis is located in Germany

> utcToZonedTime("2021-01-01T00:00:00.000Z", "UTC")
2020-12-31T23:00:00.000Z

is correct. Because if you format() this output it will show 2021-01-01 00:00:00 in Germany which is the correct representation of the input ISO date string at the UTC time zone.

The reason I have left this open is because some tests were failing in Australian time zones while passing in UK / US time zones and I haven't had time to investigate that.

ellis commented 3 years ago

@ankit-gaur @marnusw Thanks for the explanations. It's somewhat counter-intuitive for me, so I'm likely to make such mistakes again in the future, but knowing the explanation will help troubleshoot a lot faster.