mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 03:00:58 +08:00
fix(datetime): month picker no longer gives duplicate months on ios 14 and older (#24792)
resolves #24663
This commit is contained in:
@ -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()', () => {
|
||||
@ -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()', () => {
|
||||
@ -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');
|
||||
});
|
||||
})
|
||||
|
@ -282,9 +282,9 @@ 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 {
|
||||
@ -292,9 +292,34 @@ export const getPickerMonths = (
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user