diff --git a/jest.config.js b/jest.config.js index c73b4f587cc7..3d1196412681 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,5 @@ +process.env.TZ = 'UTC'; + module.exports = { verbose: false, transform: { diff --git a/packages/grafana-data/src/datetime/timezones.test.ts b/packages/grafana-data/src/datetime/timezones.test.ts new file mode 100644 index 000000000000..30f1b9d62fac --- /dev/null +++ b/packages/grafana-data/src/datetime/timezones.test.ts @@ -0,0 +1,31 @@ +import { getTimeZoneInfo } from './timezones'; +import { setTimeZoneResolver } from './common'; + +describe('getTimeZoneInfo', () => { + // global timezone is set to UTC, see jest-config.js file + + describe('IANA canonical name of the timezone', () => { + it('should resolve for default timezone', () => { + setTimeZoneResolver(() => 'browser'); + const result = getTimeZoneInfo('', Date.now()); + expect(result?.ianaName).toBe('Africa/Abidjan'); + }); + + it('should resolve for browser timezone', () => { + // global timezone is set to UTC + const result = getTimeZoneInfo('browser', Date.now()); + expect(result?.ianaName).toBe('Africa/Abidjan'); + }); + it('should resolve for utc timezone', () => { + // global timezone is set to UTC + const result = getTimeZoneInfo('utc', Date.now()); + expect(result?.ianaName).toBe('UTC'); + }); + + it('should resolve for given timezone', () => { + // global timezone is set to UTC + const result = getTimeZoneInfo('Europe/Warsaw', Date.now()); + expect(result?.ianaName).toBe('Europe/Warsaw'); + }); + }); +}); diff --git a/packages/grafana-data/src/datetime/timezones.ts b/packages/grafana-data/src/datetime/timezones.ts index 46a4c37eb3e5..e9e979a30bf3 100644 --- a/packages/grafana-data/src/datetime/timezones.ts +++ b/packages/grafana-data/src/datetime/timezones.ts @@ -30,6 +30,7 @@ export interface TimeZoneInfo { countries: TimeZoneCountry[]; abbreviation: string; offsetInMins: number; + ianaName: string; } export interface GroupedTimeZones { @@ -98,6 +99,7 @@ const mapInternal = (zone: string, timestamp: number): TimeZoneInfo | undefined case InternalTimeZones.utc: { return { name: 'Coordinated Universal Time', + ianaName: 'UTC', zone, countries: [], abbreviation: 'UTC, GMT', @@ -115,6 +117,7 @@ const mapInternal = (zone: string, timestamp: number): TimeZoneInfo | undefined abbreviation: '', offsetInMins: 0, ...info, + ianaName: (info as TimeZoneInfo).ianaName, name: 'Default', zone, }; @@ -130,6 +133,7 @@ const mapInternal = (zone: string, timestamp: number): TimeZoneInfo | undefined offsetInMins: new Date().getTimezoneOffset(), ...info, name: 'Browser Time', + ianaName: (info as TimeZoneInfo).ianaName, zone, }; } @@ -148,13 +152,13 @@ const abbrevationWithoutOffset = (abbrevation: string): string => { const mapToInfo = (timeZone: TimeZone, timestamp: number): TimeZoneInfo | undefined => { const momentTz = moment.tz.zone(timeZone); - if (!momentTz) { return undefined; } return { name: timeZone, + ianaName: momentTz.name, zone: timeZone, countries: countriesByTimeZone[timeZone] ?? [], abbreviation: abbrevationWithoutOffset(momentTz.abbr(timestamp)),