diff --git a/lib/Datepicker/Calendar.js b/lib/Datepicker/Calendar.js index e013d392d..117251dee 100644 --- a/lib/Datepicker/Calendar.js +++ b/lib/Datepicker/Calendar.js @@ -124,7 +124,10 @@ class Calendar extends React.Component { constructor(props) { super(props); - moment.locale(this.props.intl.locale || this.props.locale); + const computedLocale = this.props.intl.locale || this.props.locale; + if (moment.locales().includes(computedLocale)) { + moment.locale(computedLocale); + } const { selectedDate, dateFormat } = this.props; diff --git a/lib/Datepicker/tests/Datepicker-test.js b/lib/Datepicker/tests/Datepicker-test.js index fbeb181a3..67704ba08 100644 --- a/lib/Datepicker/tests/Datepicker-test.js +++ b/lib/Datepicker/tests/Datepicker-test.js @@ -594,6 +594,8 @@ describe('Datepicker', () => { await datepicker.openCalendar(); }); + it('does not poison moment locale cache', () => expect(moment.locales()).to.not.include('en-se')); + it('renders Monday as the first day of the week', () => Weekday('Mon', { index: 0 }).exists()); it('renders weekday and month days in correct alignment', async () => { diff --git a/lib/Timepicker/TimeDropdown.js b/lib/Timepicker/TimeDropdown.js index 6ad159034..91f01551c 100644 --- a/lib/Timepicker/TimeDropdown.js +++ b/lib/Timepicker/TimeDropdown.js @@ -50,7 +50,9 @@ class TimeDropdown extends React.Component { constructor(props) { super(props); - moment.locale(this.props.locale); + if (moment.locales().includes(this.props.locale)) { + moment.locale(this.props.locale); + } // handle existing value... let initMoment; diff --git a/lib/Timepicker/tests/Timepicker-test.js b/lib/Timepicker/tests/Timepicker-test.js index ef03ea5be..86ce92f13 100644 --- a/lib/Timepicker/tests/Timepicker-test.js +++ b/lib/Timepicker/tests/Timepicker-test.js @@ -1,6 +1,8 @@ +import { expect } from 'chai'; import React from 'react'; import { describe, beforeEach, it } from 'mocha'; -import moment from 'moment-timezone'; +import moment from 'moment'; +import momentTz from 'moment-timezone'; import { runAxeTest, HTML, @@ -107,6 +109,21 @@ describe('Timepicker', () => { it('emits an event with the time formatted as displayed', () => converge(() => (timeOutput === '05:00 PM'))); }); + describe('correctly handles unknown locales (en-SE)', () => { + beforeEach(async () => { + await mountWithContext( + + ); + + await timepicker.clickInput(); + }); + + it('does not poison moment locale cache', () => expect(moment.locales()).to.not.include('en-se')); + }); + describe('selecting a time with timeZone prop', () => { let timeOutput; @@ -166,7 +183,7 @@ describe('Timepicker', () => { await timepicker.fillIn('05:00 PM'); }); - it('returns an ISO 8601 time string for specific time zone', () => converge(() => (timeOutput === moment().tz(tz).isDST() ? '00:00:00.000Z' : '01:00:00.000Z'))); + it('returns an ISO 8601 time string for specific time zone', () => converge(() => (timeOutput === momentTz().tz(tz).isDST() ? '00:00:00.000Z' : '01:00:00.000Z'))); }); }); diff --git a/util/dateTimeUtils.js b/util/dateTimeUtils.js index 5f90f7bc0..d95fa7559 100644 --- a/util/dateTimeUtils.js +++ b/util/dateTimeUtils.js @@ -48,7 +48,9 @@ export const getLocaleDateFormat = ({ intl }) => { format = getMomentLocalizedFormat(intl); } - return format; + // replace narrow non-breaking space introduced in ICU 72.1 + // see https://github.com/nodejs/node/issues/46123 + return format.replaceAll('\u202f', ' '); }; // getLocalizedTimeFormatInfo() - @@ -128,7 +130,7 @@ export function getLocalizedTimeFormatInfo(locale) { return { ...formatInfo, - timeFormat, + timeFormat: timeFormat.replaceAll('\u202f', ' '), dayPeriods: [...dpOptions], }; }