Skip to content

Instantly share code, notes, and snippets.

@ianldgs
Last active October 6, 2022 09:21
Show Gist options
  • Save ianldgs/87ed392c6eef53ebf7df234b67f587f2 to your computer and use it in GitHub Desktop.
Save ianldgs/87ed392c6eef53ebf7df234b67f587f2 to your computer and use it in GitHub Desktop.
DayJS Zoned
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;
}
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');
};
};
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