iamkun / iamkun/dayjs

Looks like the documentation could be improved to make the behavior of the `tz` function more understandable.

Open
#2,525 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
JavaScript
Stars
48.7k
Forks
2.5k
PR merge metrics
No merged PRs in 30d

Description

Hello.
I have been using the `tz` function in various cases in my product.
In the process, I had written code that behaved differently than I had intended.

I didn't seem to have read the documentation on that point,
I would like to make a suggestion to improve the documentation so that the next person will not have the same question.

The idea is to add the following text in the [Parsing in Zone](https://day.js.org/docs/en/timezone/parsing-in-zone) page.

```
`dayjs.tz(new Date('2013-11-18'), timezone)` and `dayjs.tz('2013-11-18', timezone)`
different results.

To do Parsing in Zone, the first argument must be a date-time string.
```
## background

I see four ways to use this `tz` function
In my time zone of Japan(Asia/Tokyo), I get the following results.

```
// [Notation 1] '2023-12-25 00:00:00' converted to 'Pacific/Honolulu' time zone
dayjs("2023-12-25 00:00:00").tz("Pacific/Honolulu")
=> "2023-12-24T05:00:00-10:00"

// [Notation 2] Set '2023-12-25 00:00:00' to be in the 'Pacific/Honolulu' time zone
dayjs.tz("2023-12-25 00:00:00", "Pacific/Honolulu")
=> "2023-12-25T00:00:00-10:00"

// [Notation 3] Replacing the date-time string in Notation 2 with a date type
dayjs.tz(new Date('2023-12-25 00:00:00'), "Pacific/Honolulu")
=> "2023-12-24T05:00:00-10:00"

// [Notation 4] [Notation 4] parse string format and parse in 'Pacific/Honolulu' time zone
dayjs.tz("12-25-2023 00:00:00", "MM-DD-YYYY ss:mm:HH", "Pacific/Honolulu")
=> "2023-12-25T00:00:00-10:00"

```

Notation 1 and 3 produce the same result, but not the same result as notation 2.
The reason for this is the following implementation.

https://github.com/iamkun/dayjs/blob/dev/src/plugin/timezone/index.js

```javascript
d.tz = function (input, arg1, arg2) {
const parseFormat = arg2 && arg1
const timezone = arg2 || arg1 || defaultTimezone
const previousOffset = tzOffset(+d(), timezone)
if (typeof input !== 'string') {
// timestamp number || js Date || Day.js
return d(input).tz(timezone)
}
const localTs = d.utc(input, parseFormat).valueOf()
const [targetTs, targetOffset] = fixOffset(localTs, previousOffset, timezone)
const ins = d(targetTs).utcOffset(targetOffset)
ins.$x.$timezone = timezone
return ins
}
```

The documentation on the Parsing in Zone page says `Parse date-time string`.
On the other hand, if input also accepts a string type and is not a string type, then `d(input).tz(timezone)`.

So notation 1 and 3 return the same result.
I used to think that I could get the same result as notation 2 with `dayjs.tz(dateObject, timezone)`.
Perhaps some of you have the same misconception.
By updating the documentation, I believe we can save those people time and trouble.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.