Last active
October 6, 2022 09:21
-
-
Save ianldgs/87ed392c6eef53ebf7df234b67f587f2 to your computer and use it in GitHub Desktop.
DayJS Zoned
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Dayjs, PluginFunc, ConfigType } from 'dayjs'; | |
declare const plugin: PluginFunc; | |
export = plugin; | |
declare module 'dayjs' { | |
/** Similar to date-fns/utcToZonedTime */ | |
function utcToZoned(config: ConfigType, timezone?: string): Dayjs; | |
/** Similar to date-fns/zonedTimeToUtc */ | |
function zonedToUtc(config: ConfigType, timezone?: string): Dayjs; | |
/** | |
* Will change timezones, but keep the same day/month/year hours:minutes, | |
* by adding or subtracting the difference between the `config` on `oldTimezone` and `newTimezone` | |
*/ | |
function changeZoneKeepTime( | |
config: ConfigType, | |
oldTimezone: string, | |
newTimezone: string | |
): Dayjs; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default (_, Dayjs, dayjs) => { | |
dayjs.utcToZoned = function utcToZoned(config, timeZone) { | |
const date = dayjs(config); | |
if (!timeZone) return date; | |
const zonedString = date.toDate().toLocaleString('en-US', { timeZone }); | |
return dayjs(zonedString); | |
}; | |
dayjs.zonedToUtc = function zonedToUtc(config, timeZone) { | |
const utcDate = dayjs(config); | |
if (!timeZone) return utcDate; | |
const zonedDate = dayjs.utcToZoned(config, timeZone); | |
const diff = utcDate.diff(zonedDate, 'hour'); | |
return utcDate.add(diff, 'hour'); | |
}; | |
dayjs.changeZoneKeepTime = function changeZoneKeepTime( | |
config, | |
oldTimeZone, | |
newTimeZone | |
) { | |
const utcDate = dayjs(config); | |
if (!oldTimeZone || !newTimeZone) return utcDate; | |
const oldDate = dayjs.utcToZoned(config, oldTimeZone); | |
const newDate = dayjs.utcToZoned(config, newTimeZone); | |
const diff = oldDate.diff(newDate, 'hour'); | |
return utcDate.add(diff, 'hour'); | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import dayjs from 'dayjs'; | |
import plugin from './dayjs-zoned'; | |
dayjs.extend(plugin); | |
// This test does not work inside Electron. See https://github.com/cypress-io/cypress/issues/1043 | |
describe('utcToZoned', () => { | |
it('works with strings', () => { | |
assert.equal( | |
dayjs.utcToZoned('2019-11-10T18:00:16.000Z', 'America/Sao_Paulo').toISOString(), | |
'2019-11-10T14:00:16.000Z' | |
); | |
assert.equal( | |
dayjs.utcToZoned('2019-11-10T19:00:16.000Z', 'America/Sao_Paulo').toISOString(), | |
'2019-11-10T15:00:16.000Z' | |
); | |
}); | |
it('works with Dates', () => { | |
assert.equal( | |
dayjs | |
.utcToZoned(new Date('2019-11-10T18:00:16.000Z'), 'America/Sao_Paulo') | |
.toISOString(), | |
'2019-11-10T14:00:16.000Z' | |
); | |
assert.equal( | |
dayjs | |
.utcToZoned(new Date('2019-11-10T19:00:16.000Z'), 'America/Sao_Paulo') | |
.toISOString(), | |
'2019-11-10T15:00:16.000Z' | |
); | |
}); | |
}); | |
describe('zonedToUtc', () => { | |
it('works with strings', () => { | |
assert.equal( | |
dayjs.zonedToUtc('2019-11-10T18:00:16.000Z', 'America/Sao_Paulo').toISOString(), | |
'2019-11-10T22:00:16.000Z' | |
); | |
assert.equal( | |
dayjs.zonedToUtc('2019-11-10T19:00:16.000Z', 'America/Sao_Paulo').toISOString(), | |
'2019-11-10T23:00:16.000Z' | |
); | |
}); | |
it('works with Dates', () => { | |
assert.equal( | |
dayjs | |
.zonedToUtc(new Date('2019-11-10T18:00:16.000Z'), 'America/Sao_Paulo') | |
.toISOString(), | |
'2019-11-10T22:00:16.000Z' | |
); | |
assert.equal( | |
dayjs | |
.zonedToUtc(new Date('2019-11-10T19:00:16.000Z'), 'America/Sao_Paulo') | |
.toISOString(), | |
'2019-11-10T23:00:16.000Z' | |
); | |
}); | |
}); | |
describe('changeZoneKeepTime', () => { | |
it('Converts NYC to AMS', () => { | |
const americaNewYorkInUTC = '2019-10-31T02:00:00.000Z'; // 10 pm | |
const europeAmsterdamInUTC = '2019-10-30T21:00:00.000Z'; // 10 pm | |
assert.equal( | |
dayjs | |
.changeZoneKeepTime(americaNewYorkInUTC, 'America/New_York', 'Europe/Amsterdam') | |
.toISOString(), | |
europeAmsterdamInUTC | |
); | |
}); | |
it('Converts AMS to SP', () => { | |
const europeAmsterdamInUTC = '2019-10-30T13:00:00.000Z'; // 2 pm | |
const americaSaoPauloInUTC = '2019-10-30T17:00:00.000Z'; // 2 pm | |
assert.equal( | |
dayjs | |
.changeZoneKeepTime(europeAmsterdamInUTC, 'Europe/Amsterdam', 'America/Sao_Paulo') | |
.toISOString(), | |
americaSaoPauloInUTC | |
); | |
}); | |
it('Converts SP to AMS', () => { | |
const americaSaoPauloInUTC = '2019-10-30T12:00:00.000Z'; // 9 am | |
const europeAmsterdamInUTC = '2019-10-30T08:00:00.000Z'; // 9 am | |
assert.equal( | |
dayjs | |
.changeZoneKeepTime(americaSaoPauloInUTC, 'America/Sao_Paulo', 'Europe/Amsterdam') | |
.toISOString(), | |
europeAmsterdamInUTC | |
); | |
}); | |
it('Does nothing AMS to AMS', () => { | |
const europeAmsterdamInUTC = '2019-10-30T10:00:00.000Z'; // 11 am | |
assert.equal( | |
dayjs | |
.changeZoneKeepTime(europeAmsterdamInUTC, 'Europe/Amsterdam', 'Europe/Amsterdam') | |
.toISOString(), | |
europeAmsterdamInUTC | |
); | |
}); | |
it('Does nothing AMS to BERL', () => { | |
const europeAmsterdamInUTC = '2019-10-30T10:00:00.000Z'; // 11 am | |
assert.equal( | |
dayjs | |
.changeZoneKeepTime(europeAmsterdamInUTC, 'Europe/Amsterdam', 'Europe/Berlin') | |
.toISOString(), | |
europeAmsterdamInUTC | |
); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment