Skip to content

Conversation

@Ayo1984
Copy link
Contributor

@Ayo1984 Ayo1984 commented Oct 29, 2025

When parsing UTC timestamps (e.g. containing Z or +00:00) while a default timezone is set, Day.js currently reapplies the default timezone offset, resulting in incorrect conversions.

This PR updates the timezone plugin to correctly detect UTC input and preserve its UTC value instead of re-offsetting.

Resolves #2946

const hasExplicitOffset = /[Zz]|[+-]\d\d:?(\d\d)?$/.test(input)
if (hasExplicitOffset) {
const utcDate = d.utc(input, parseFormat)
utcDate.$x.$timezone = timezone

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing it this way doesn't set the offset or any of the time fields so the resulting object likely doesn't do what you think it does here. It's also not covered by test cases, your input is UTC (not an offset), toISOString is always UTC, so comparing it to moment will pass with any value for timezone.

return d(input).tz(timezone)
}

const hasExplicitOffset = /[Zz]|[+-]\d\d:?(\d\d)?$/.test(input)
Copy link
Owner

@iamkun iamkun Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const hasTimezoneInfo = /Z|[+-]\d{2}:?\d{2}$/.test(input)
if (hasTimezoneInfo && !parseFormat) {
return d(input).tz(timezone)
}
Can we fix it in this way?

  • Detect if the input string has timezone markers (Z or +HH:MM)
  • If yes & no custom format: Let dayjs parse it normally (which correctly handles UTC), then convert to target timezone
  • If no: Keep existing behavior (treat as local time in target timezone)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sounds good, will run a few tests

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

Successfully merging this pull request may close these issues.

dayjs.tz parses ISO string as local time instead of UTC

3 participants