chrono icon indicating copy to clipboard operation
chrono copied to clipboard

Relative date parser always uses device-local time

Open CGamesPlay opened this issue 3 years ago • 0 comments

I am using chrono 2.3.8. When I parse a relative date, the device local time zone is used, despite the reference time explicitly including a time zone. Here is a test case:

  it.only("chrono test", () => {
    const cases = [
      ["2021-02-14T12:00:00.000Z", "2021-02-13T00:00:00.000Z"],
      ["2021-02-14T00:01:00.000Z", "2021-02-13T00:01:00.000Z"],
      ["2021-02-14T23:59:00.000Z", "2021-02-13T00:59:00.000Z"],
    ];

    const actual = cases.map(([input, _]) => {
      const parsed = parser.parse("1 day ago", {
        instant: new Date(input),
        timezone: 0,
      })[0];
      return parsed.date().toISOString();
    });

    expect(actual).toEqual(cases.map(([_, expected]) => expected));
  });

To run this test, use the test runner but make sure the environment variable TZ=0 is set. For me, that TZ=0 jest. The tests will pass, because the device time is UTC. Now run the tests with TZ=:Asia/Jakarta (or leave it empty if your device is not in UTC). The tests fail:

- Expected  - 3
+ Received  + 3

  Array [
-   "2021-02-13T00:00:00.000Z",
-   "2021-02-13T00:01:00.000Z",
-   "2021-02-13T00:59:00.000Z",
+   "2021-02-12T17:00:00.000Z",
+   "2021-02-12T17:01:00.000Z",
+   "2021-02-13T17:59:00.000Z",
  ]

The times have been parsed in the device time zone, despite chrono being explicitly told to parse them in UTC. Changing timezone: 0 to any other value does not resolve the issue, it appears to be ignored.

Side note: When parsing "1 day ago", why are hours set to 0 but minutes preserved?

CGamesPlay avatar May 02 '22 10:05 CGamesPlay