dmtrKovalenko / dmtrKovalenko/date-io

Support for Timezones

Open
#609 5 comments 6 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
754
Forks
92
PR merge metrics
No merged PRs in 30d

Description

date-io currently doesn't handle timezones at all. Or it stays blind to timezones and assumes you never pass it anything but a local time, because passing it an externally zoned date gives inconsistent results.

It does at least appear consistent for `.date()` created dates. However the date-io users are libraries so it's no guarantee that the users using those libraries create their dates with the date-io `.date()` function. Most likely they choose a library, create dates with that library, and pass those dates to a library that happens to use a date-io adapter.

## Current behavior
Luxon uses the DateTime's timezone when calculating startOfDay and formats ISO timestamps according to the DateTime's zone.
```js
const {DateTime} = require('luxon')
const LuxonUtils = require('@date-io/luxon')
const ioLuxon = new LuxonUtils();
ioLuxon.toISO(ioLuxon.startOfDay(DateTime.local()));
// '2022-02-25T00:00:00.000-08:00'
ioLuxon.toISO(ioLuxon.startOfDay(DateTime.utc()));
// '2022-02-25T00:00:00.000Z'
ioLuxon.toISO(ioLuxon.startOfDay(ioLuxon.date('2022-02-25T00:00:00.000Z')));
// '2022-02-24T00:00:00.000-08:00'
```

Moment uses the DateTime'z timezone when calculating startOfDay, but formats ISO timestamps always in UTC.
```js
const MomentUtils = require('@date-io/moment')
const moment = require('moment')
const ioMoment = new MomentUtils()
ioMoment.toISO(ioMoment.startOfDay(moment()));
// '2022-02-25T08:00:00.000Z'
ioMoment.toISO(ioMoment.startOfDay(moment.utc()));
// '2022-02-25T00:00:00.000Z'
ioMoment.toISO(ioMoment.startOfDay(ioMoment.date('2022-02-25T00:00:00.000Z')));
// '2022-02-24T08:00:00.000Z'
```

date-fns uses the local timezone when calculating startOfDay and always formats timestamps in the local time. Since despite date-fns-tz existing, date-fns appears to not actually support calculations knowledgable about other timezones.
```js
const {zonedTimeToUtc} = require('date-fns-tz')
const DateFnsUtils = require('@date-io/date-fns')
const ioDateFns = new DateFnsUtils();
ioDateFns.toISO(ioDateFns.startOfDay(new Date));
// '2022-02-25T00:00:00-08:00'
ioDateFns.toISO(ioDateFns.startOfDay(zonedTimeToUtc(new Date)));
// '2022-02-25T00:00:00-08:00'
ioDateFns.toISO(ioDateFns.startOfDay(ioDateFns.date('2022-02-25T00:00:00.000Z')));
// '2022-02-24T00:00:00-08:00'
```

However date-io doesn't handle them at all. Or rather it stays blind to the timezone leaving different results

## Expected behaviour
I think we should add a timeZone option to the adapter options and aim for relative consistency between libraries.

- Setting timeZone to 'utc' should make luxon and moment adapters use their `.utc()` functions in .date()
- Setting it to another time zone should make luxon and moment adapters use their `.setZone()` and `.tz()` functions to change the zone
- For moment this should probably error out if the moment implementation isn't set to moment-timezone
- Either of these options should make the date-fns adapter error out since it doesn't support other time zones
- startOfDay calculations should be made in the timeZone option's timezone (i.e. if `timeZone: undefined` we should be switching luxon and moment's dates in other zones to local time before doing that calculation)
- luxon and moment should probably also format ISOs in the `timeZone` option's zone

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.