Update/Improve timezone handling

This commit is contained in:
Matthias 2022-06-05 14:27:51 +02:00
parent 53890b70c1
commit 9d7748b504
4 changed files with 83 additions and 30 deletions

View File

@ -11,7 +11,7 @@ import NavBar from '@/components/layout/NavBar.vue';
import NavFooter from '@/components/layout/NavFooter.vue'; import NavFooter from '@/components/layout/NavFooter.vue';
import Body from '@/components/layout/Body.vue'; import Body from '@/components/layout/Body.vue';
import { setTimezone } from './shared/formatters'; import { setTimezone } from './shared/formatters';
import { defineComponent, onMounted } from '@vue/composition-api'; import { defineComponent, onMounted, watch } from '@vue/composition-api';
import { useSettingsStore } from './stores/settings'; import { useSettingsStore } from './stores/settings';
export default defineComponent({ export default defineComponent({
@ -22,6 +22,13 @@ export default defineComponent({
onMounted(() => { onMounted(() => {
setTimezone(settingsStore.timezone); setTimezone(settingsStore.timezone);
}); });
watch(
() => settingsStore.timezone,
(tz) => {
console.log('timezone changed', tz);
setTimezone(tz);
},
);
return {}; return {};
}, },
}); });

View File

@ -20,19 +20,11 @@ function getTimeZone(tz?: string): string {
return tz || locTimeZone; return tz || locTimeZone;
} }
/** function formatDate(date: Date, formatPattern: string, timezone?: string): string {
* const timezoneRes = getTimeZone(timezone);
* @param ts Convert timestamp or Date to datetime (in correct timezone) return format(utcToZonedTime(date, timezoneRes), formatPattern, {
* @param timezone timezone to use timeZone: timezoneRes,
* @returns Date object (in timezone) });
*/
function convertToDate(ts: number | Date, timezone?: string): Date {
const date = toDate(ts);
const currentTz = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (getTimeZone(timezone) === 'UTC') {
return utcToZonedTime(date, currentTz);
}
return date;
} }
/** /**
@ -40,7 +32,7 @@ function convertToDate(ts: number | Date, timezone?: string): Date {
* @param ts Timestamp as number or date (in utc!!) * @param ts Timestamp as number or date (in utc!!)
*/ */
export function timestampms(ts: number | Date): string { export function timestampms(ts: number | Date): string {
return format(convertToDate(ts), 'yyyy-MM-dd HH:mm:ss', { timeZone: locTimeZone }); return formatDate(toDate(ts), 'yyyy-MM-dd HH:mm:ss');
} }
/** /**
@ -50,9 +42,7 @@ export function timestampms(ts: number | Date): string {
* @returns formatted date in desired timezone (or globally configured timezone) * @returns formatted date in desired timezone (or globally configured timezone)
*/ */
export function timestampmsWithTimezone(ts: number | Date, timezone?: string): string { export function timestampmsWithTimezone(ts: number | Date, timezone?: string): string {
return format(convertToDate(ts, timezone), 'yyyy-MM-dd HH:mm:ss (z)', { return formatDate(toDate(ts), 'yyyy-MM-dd HH:mm:ss (z)', timezone);
timeZone: getTimeZone(timezone),
});
} }
/** /**
@ -60,7 +50,7 @@ export function timestampmsWithTimezone(ts: number | Date, timezone?: string): s
* @param ts * @param ts
*/ */
export function timestampToDateString(ts: number | Date): string { export function timestampToDateString(ts: number | Date): string {
return format(convertToDate(ts), 'yyyy-MM-dd'); return formatDate(toDate(ts), 'yyyy-MM-dd');
} }
/** /**
@ -72,7 +62,7 @@ export function dateStringToTimeRange(datestring: string): string {
} }
export function timestampHour(ts: number): number { export function timestampHour(ts: number): number {
return getHours(convertToDate(ts)); return Number(formatDate(toDate(ts), 'HH'));
} }
/** /**
@ -90,3 +80,8 @@ export default {
dateStringToTimeRange, dateStringToTimeRange,
setTimezone, setTimezone,
}; };
export const exportForTesting = {
getTimeZone,
formatDate,
};

View File

@ -44,16 +44,6 @@ export const useSettingsStore = defineStore('uiSettings', {
}, },
}, },
actions: { actions: {
setOpenTradesInTitle(locked: string) {
this.openTradesInTitle = locked;
},
setTimeZone(timezone: string) {
setTimezone(timezone);
this.timezone = timezone;
},
setBackgroundSync(value: boolean) {
this.backgroundSync = value;
},
async loadUIVersion() { async loadUIVersion() {
if (import.meta.env.PROD) { if (import.meta.env.PROD) {
try { try {

View File

@ -0,0 +1,61 @@
import {
exportForTesting,
timestampms,
timestampmsWithTimezone,
setTimezone,
timestampToDateString,
dateStringToTimeRange,
timestampHour,
} from '@/shared/formatters';
const { getTimeZone } = exportForTesting;
// 1651057500000 = 2022-04-27T11:05:00+00:00
describe('timeformatter.ts', () => {
it('sets timezone correctly', () => {
expect(getTimeZone() == 'UTC');
expect(getTimeZone(undefined) == 'UTC');
setTimezone('CET');
expect(getTimeZone() == 'CET');
setTimezone('UTC');
expect(getTimeZone() == 'UTC');
});
it('timestampmsWithTimezone convert correctly', () => {
expect(getTimeZone(undefined) == 'UTC');
setTimezone('UTC');
expect(timestampmsWithTimezone(1651057500000, 'CET')).toEqual('2022-04-27 13:05:00 (GMT+2)');
expect(timestampmsWithTimezone(1651057500000, 'UTC')).toEqual('2022-04-27 11:05:00 (UTC)');
expect(timestampmsWithTimezone(1651057500000)).toEqual('2022-04-27 11:05:00 (UTC)');
setTimezone('UTC');
expect(timestampmsWithTimezone(1651057500000)).toEqual('2022-04-27 11:05:00 (UTC)');
});
it('timestampms convert correctly', () => {
setTimezone('UTC');
expect(timestampms(1651057500000)).toEqual('2022-04-27 11:05:00');
setTimezone('CET');
expect(timestampms(1651057500000)).toEqual('2022-04-27 13:05:00');
});
it('timestampToDateString converts to date', () => {
expect(timestampToDateString(1651057500000)).toEqual('2022-04-27');
// Set close to midnight - so timezone matters
// 2022-04-27T11:26:19 UTC
const timestamp = 1651101979000;
setTimezone('UTC');
expect(timestampToDateString(timestamp)).toEqual('2022-04-27');
setTimezone('CET');
expect(timestampToDateString(timestamp)).toEqual('2022-04-28');
});
it('dateStringToTimeRange converts to correct timerange', () => {
expect(dateStringToTimeRange('2022-04-28')).toEqual('20220428');
expect(dateStringToTimeRange('2019-04-01')).toEqual('20190401');
});
it('timestampHour converts', () => {
// Hour conversion
setTimezone('UTC');
expect(timestampHour(1651057500000)).toEqual(11);
setTimezone('CET');
expect(timestampHour(1651057500000)).toEqual(13);
});
});