Skip to content

Commit

Permalink
fix(datetime): month picker no longer gives duplicate months on ios 1…
Browse files Browse the repository at this point in the history
…4 and older (#24792)

resolves #24663
  • Loading branch information
liamdebeasi authored Feb 23, 2022
1 parent b0ac7de commit b6d7e1c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 11 deletions.
23 changes: 22 additions & 1 deletion core/src/components/datetime/test/format.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ describe('generateDayAriaLabel()', () => {

expect(generateDayAriaLabel('en-US', false, reference)).toEqual('Monday, May 31');
});
it('should return Saturday, April 1', () => {
const reference = { month: 4, day: 1, year: 2006 };

expect(generateDayAriaLabel('en-US', false, reference)).toEqual('Saturday, April 1');
});
});

describe('getMonthAndDay()', () => {
Expand All @@ -37,6 +42,14 @@ describe('getMonthAndDay()', () => {
it('should return mar, 11 may', () => {
expect(getMonthAndDay('es-ES', { month: 5, day: 11, year: 2021 })).toEqual('mar, 11 may');
});

it('should return Sat, Apr 1', () => {
expect(getMonthAndDay('en-US', { month: 4, day: 1, year: 2006 })).toEqual('Sat, Apr 1');
});

it('should return sáb, 1 abr', () => {
expect(getMonthAndDay('es-ES', { month: 4, day: 1, year: 2006 })).toEqual('sáb, 1 abr');
});
})

describe('getFormattedHour()', () => {
Expand All @@ -63,7 +76,15 @@ describe('getMonthAndYear()', () => {
expect(getMonthAndYear('en-US', { month: 5, day: 11, year: 2021 })).toEqual('May 2021');
});

it('should return mar, 11 may', () => {
it('should return mayo de 2021', () => {
expect(getMonthAndYear('es-ES', { month: 5, day: 11, year: 2021 })).toEqual('mayo de 2021');
});

it('should return April 2006', () => {
expect(getMonthAndYear('en-US', { month: 4, day: 1, year: 2006 })).toEqual('April 2006');
});

it('should return abril de 2006', () => {
expect(getMonthAndYear('es-ES', { month: 4, day: 1, year: 2006 })).toEqual('abril de 2006');
});
})
33 changes: 29 additions & 4 deletions core/src/components/datetime/utils/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,19 +282,44 @@ export const getPickerMonths = (
}

processedMonths.forEach(processedMonth => {
const date = new Date(`${processedMonth}/1/${year}`);
const date = new Date(`${processedMonth}/1/${year} GMT+0000`);

const monthString = new Intl.DateTimeFormat(locale, { month: 'long' }).format(date);
const monthString = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' }).format(date);
months.push({ text: monthString, value: processedMonth });
});
} else {
const maxMonth = maxParts && maxParts.year === year ? maxParts.month : 12;
const minMonth = minParts && minParts.year === year ? minParts.month : 1;

for (let i = minMonth; i <= maxMonth; i++) {
const date = new Date(`${i}/1/${year}`);

const monthString = new Intl.DateTimeFormat(locale, { month: 'long' }).format(date);
/**
*
* There is a bug on iOS 14 where
* Intl.DateTimeFormat takes into account
* the local timezone offset when formatting dates.
*
* Forcing the timezone to 'UTC' fixes the issue. However,
* we should keep this workaround as it is safer. In the event
* this breaks in another browser, we will not be impacted
* because all dates will be interpreted in UTC.
*
* Example:
* new Intl.DateTimeFormat('en-US', { month: 'long' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "March"
* new Intl.DateTimeFormat('en-US', { month: 'long', timeZone: 'UTC' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "April"
*
* In certain timezones, iOS 14 shows the wrong
* date for .toUTCString(). To combat this, we
* force all of the timezones to GMT+0000 (UTC).
*
* Example:
* Time Zone: Central European Standard Time
* new Date('1/1/1992').toUTCString() // "Tue, 31 Dec 1991 23:00:00 GMT"
* new Date('1/1/1992 GMT+0000').toUTCString() // "Wed, 01 Jan 1992 00:00:00 GMT"
*/
const date = new Date(`${i}/1/${year} GMT+0000`);

const monthString = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' }).format(date);
months.push({ text: monthString, value: i });
}
}
Expand Down
12 changes: 6 additions & 6 deletions core/src/components/datetime/utils/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ export const generateDayAriaLabel = (locale: string, today: boolean, refParts: D
/**
* MM/DD/YYYY will return midnight in the user's timezone.
*/
const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year}`);
const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year} GMT+0000`);

const labelString = new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric' }).format(date);
const labelString = new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric', timeZone: 'UTC' }).format(date);

/**
* If date is today, prepend "Today" so screen readers indicate
Expand All @@ -72,8 +72,8 @@ export const generateDayAriaLabel = (locale: string, today: boolean, refParts: D
* Used for the header in MD mode.
*/
export const getMonthAndDay = (locale: string, refParts: DatetimeParts) => {
const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year}`);
return new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric' }).format(date);
const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year} GMT+0000`);
return new Intl.DateTimeFormat(locale, { weekday: 'short', month: 'short', day: 'numeric', timeZone: 'UTC' }).format(date);
}

/**
Expand All @@ -83,6 +83,6 @@ export const getMonthAndDay = (locale: string, refParts: DatetimeParts) => {
* Example: May 2021
*/
export const getMonthAndYear = (locale: string, refParts: DatetimeParts) => {
const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year}`);
return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' }).format(date);
const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year} GMT+0000`);
return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' }).format(date);
}

0 comments on commit b6d7e1c

Please sign in to comment.