diff --git a/src/libs/IntlPolyfill/index.native.ts b/src/libs/IntlPolyfill/index.native.ts index 9e578558fae..d81b9d90cbe 100644 --- a/src/libs/IntlPolyfill/index.native.ts +++ b/src/libs/IntlPolyfill/index.native.ts @@ -1,6 +1,7 @@ import polyfillNumberFormat from './polyfillNumberFormat'; import polyfillListFormat from './polyfillListFormat'; import IntlPolyfill from './types'; +import polyfillDateTimeFormat from './polyfillDateTimeFormat'; /** * Polyfill the Intl API, always performed for native devices. @@ -10,8 +11,8 @@ const intlPolyfill: IntlPolyfill = () => { require('@formatjs/intl-getcanonicallocales/polyfill'); require('@formatjs/intl-locale/polyfill'); require('@formatjs/intl-pluralrules/polyfill'); - require('@formatjs/intl-datetimeformat'); polyfillNumberFormat(); + polyfillDateTimeFormat(); polyfillListFormat(); }; diff --git a/src/libs/IntlPolyfill/index.ts b/src/libs/IntlPolyfill/index.ts index bef12ef093e..be3e392b35c 100644 --- a/src/libs/IntlPolyfill/index.ts +++ b/src/libs/IntlPolyfill/index.ts @@ -1,13 +1,13 @@ import polyfillNumberFormat from './polyfillNumberFormat'; import IntlPolyfill from './types'; +import polyfillDateTimeFormat from './polyfillDateTimeFormat'; /** * Polyfill the Intl API if the ICU version is old. * This ensures that the currency data is consistent across platforms and browsers. */ const intlPolyfill: IntlPolyfill = () => { - // Just need to polyfill Intl.NumberFormat for web based platforms polyfillNumberFormat(); - require('@formatjs/intl-datetimeformat'); + polyfillDateTimeFormat(); }; export default intlPolyfill; diff --git a/src/libs/IntlPolyfill/polyfillDateTimeFormat.ts b/src/libs/IntlPolyfill/polyfillDateTimeFormat.ts new file mode 100644 index 00000000000..25983aa71f5 --- /dev/null +++ b/src/libs/IntlPolyfill/polyfillDateTimeFormat.ts @@ -0,0 +1,52 @@ +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '../../ONYXKEYS'; +import {Timezone} from '../../types/onyx/PersonalDetails'; +import CONST from '../../CONST'; + +let currentUserAccountID: number | undefined; +Onyx.connect({ + key: ONYXKEYS.SESSION, + callback: (val) => { + // When signed out, val is undefined + if (!val) { + return; + } + + currentUserAccountID = val.accountID; + }, +}); + +let timezone: Required = CONST.DEFAULT_TIME_ZONE; +Onyx.connect({ + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + callback: (value) => { + if (!currentUserAccountID) { + return; + } + + const personalDetailsTimezone = value?.[currentUserAccountID]?.timezone; + + timezone = { + selected: personalDetailsTimezone?.selected ?? CONST.DEFAULT_TIME_ZONE.selected, + automatic: personalDetailsTimezone?.automatic ?? CONST.DEFAULT_TIME_ZONE.automatic, + }; + }, +}); + +export default function () { + // Because JS Engines do not expose default timezone, the polyfill cannot detect local timezone that a browser is in. + // We must manually do this by getting the local timezone before adding polyfill. + const currentTimezone = timezone.automatic ? Intl.DateTimeFormat().resolvedOptions().timeZone : timezone.selected; + + require('@formatjs/intl-datetimeformat/polyfill-force'); + require('@formatjs/intl-datetimeformat/locale-data/en'); + require('@formatjs/intl-datetimeformat/locale-data/es'); + require('@formatjs/intl-datetimeformat/add-all-tz'); + + if ('__setDefaultTimeZone' in Intl.DateTimeFormat) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + // eslint-disable-next-line no-underscore-dangle + Intl.DateTimeFormat.__setDefaultTimeZone(currentTimezone); + } +}