Skip to content
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

Setting identical timezone to the current timezone subtracts an hour #1690

Open
AntJanus opened this issue Nov 10, 2021 · 3 comments
Open

Setting identical timezone to the current timezone subtracts an hour #1690

AntJanus opened this issue Nov 10, 2021 · 3 comments

Comments

@AntJanus
Copy link

Describe the bug
In the timezone plugin, setting a timezone to a date can result in subtracting an hour when it wasn't supposed to be.

const today = dayjs('2021-10-10T23:00:00.000Z').tz('America/Los_Angeles') // converts to 4pm
const todayPacific = dayjs(today).tz('America/Los_Angeles') // converts to 3pm 

The culprit is this line: https://github.com/iamkun/dayjs/blob/dev/src/plugin/timezone/index.js#L98

Doing const target = date.toLocalString('en-US', { timeZone: timezone}) will return a string without any timezone data so when the code executes the next line with new Date(target), that date object is no longer in the correct timezone.

Recreated this behavior here:
https://codesandbox.io/s/damp-cherry-lzv2z?file=/src/App.js

I inspected the objects -- they both are set in the correct timezone for the date (PDT) with identical offset but their Unix timestamps are off. That shouldn't happen when setting timezone data.

Expected behavior
Setting an identical timezone to a date should not change the time.

Information

  • Day.js Version 1.10.7
  • OS: MacOS Big Sur
  • Browser: Chrome 95
  • Time zone: GMT-07:00 DST (Pacific Daylight Time)
@AntJanus
Copy link
Author

Looks like outputting the desired timezone fixes this problem: https://codesandbox.io/s/cold-cherry-s3l4y?file=/src/App.js

const target = date.toLocalString('en-US', { timeZone: timezone, timeZoneName: 'short' })

@tobiashm
Copy link

As far as I can tell, the const target = date.toLocalString('en-US', { timeZone: timezone}) part is writing out the time without time zone on purpose, because it's used to calculate the difference between the 'current' time zone and the target, since the Date object is always representing the host systems time zone.
So my guess is that the date instance returned by this.toDate() on the line before is not representing the correct time. So there's definitely a problem, but I think it's already in the first .tz('…') call.

As an aside, a quick-fix for this particular issue could be to have the tz method check if the Dayjs instance is already representing the target time zone and then just return a clone, like the constructor does. But that doesn't do anything for the underlying issue.

@jhalag
Copy link

jhalag commented Feb 28, 2022

I was about to open an issue with respect to dates being parsed to/from unix timestamps being wrong after a timezone offset is applied. Came across this issue - it appears to be due to this bug. My returned times are off by one hour - out of curiosity I called dayjs.unix(ts).tz(targetTZ).tz(targetTZ).tz(targetTZ) and it's now off by three hours, not one. Probably the same bug.

Interestingly enough, version 1.0.4 does not seem to have the same behavior in my test. It is ahead by an hour, instead of behind. However multiple calls to tz() do not increase the offset, it remains the same.

I noticed in v1.0.5's commit notes:

timezone plugin DST error (#1352) (71bed15)

this is quite possibly where the behavior changed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants