Skip to content

Commit

Permalink
Ignore units not in the data type when formatting with Intl
Browse files Browse the repository at this point in the history
If the formatting options request a time zone name for any type except
Absolute, or a day for YearMonth, or a year for MonthDay, we want to
ignore that, since the data model for that type doesn't contain those
units.

Closes: #572
  • Loading branch information
ptomato authored and ryzokuken committed May 19, 2020
1 parent f49b65d commit e534d27
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 9 deletions.
33 changes: 24 additions & 9 deletions polyfill/lib/intl.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export function DateTimeFormat(locale = IntlDateTimeFormat().resolvedOptions().l

this[ORIGINAL] = new IntlDateTimeFormat(locale, options);
this[TIMEZONE] = new TimeZone(this.resolvedOptions().timeZone);
this[DATE] = new IntlDateTimeFormat(locale, dateAmend(options, {}));
this[YM] = new IntlDateTimeFormat(locale, dateAmend(options, { day: false }));
this[MD] = new IntlDateTimeFormat(locale, dateAmend(options, { year: false }));
this[DATE] = new IntlDateTimeFormat(locale, dateAmend(options));
this[YM] = new IntlDateTimeFormat(locale, yearMonthAmend(options));
this[MD] = new IntlDateTimeFormat(locale, monthDayAmend(options));
this[TIME] = new IntlDateTimeFormat(locale, timeAmend(options));
this[DATETIME] = new IntlDateTimeFormat(locale, datetimeAmend(options));
}
Expand Down Expand Up @@ -101,15 +101,15 @@ function formatRangeToParts(a, b) {

function amend(options = {}, amended = {}) {
options = ObjectAssign({}, options);
for (let opt of ['year', 'month', 'day', 'hour', 'minute', 'second']) {
for (let opt of ['year', 'month', 'day', 'hour', 'minute', 'second', 'timeZoneName']) {
options[opt] = opt in amended ? amended[opt] : options[opt];
if (options[opt] === false || options[opt] === undefined) delete options[opt];
}
return options;
}

function timeAmend(options) {
options = amend(options, { year: false, month: false, day: false });
options = amend(options, { year: false, month: false, day: false, timeZoneName: false });
if (!hasTimeOptions(options)) {
options = ObjectAssign(options, {
hour: 'numeric',
Expand All @@ -120,21 +120,36 @@ function timeAmend(options) {
return options;
}

function dateAmend(options, amendments) {
options = amend(options, { hour: false, minute: false, second: false });
function yearMonthAmend(options) {
options = amend(options, { day: false, hour: false, minute: false, second: false, timeZoneName: false });
if (!('year' in options || 'month' in options)) {
options = ObjectAssign(options, { year: 'numeric', month: 'numeric' });
}
return options;
}

function monthDayAmend(options) {
options = amend(options, { year: false, hour: false, minute: false, second: false, timeZoneName: false });
if (!('month' in options || 'day' in options)) {
options = ObjectAssign(options, { month: 'numeric', day: 'numeric' });
}
return options;
}

function dateAmend(options) {
options = amend(options, { hour: false, minute: false, second: false, timeZoneName: false });
if (!hasDateOptions(options)) {
options = ObjectAssign(options, {
year: 'numeric',
month: 'numeric',
day: 'numeric'
});
}
options = amend(options, amendments);
return options;
}

function datetimeAmend(options) {
options = ObjectAssign({}, options);
options = amend(options, { timeZoneName: false });
if (!hasTimeOptions(options) && !hasDateOptions(options)) {
ObjectAssign(options, {
year: 'numeric',
Expand Down
29 changes: 29 additions & 0 deletions polyfill/test/intl.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,63 @@ describe('Intl', () => {
equal(`${datetime.toLocaleString('en', { timeZone: 'America/New_York' })}`, '11/18/1976, 3:23:30 PM'));
it(`(${datetime.toString()}).toLocaleString('de-AT', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${datetime.toLocaleString('de', { timeZone: 'Europe/Vienna' })}`, '18.11.1976, 15:23:30'));
it('should ignore units not in the data type', () => {
equal(datetime.toLocaleString('en', { timeZoneName: 'long' }), '11/18/1976, 3:23:30 PM');
});
});
describe('time.toLocaleString()', () => {
const time = Temporal.Time.from('1976-11-18T15:23:30');
it(`(${time.toString()}).toLocaleString('en-US', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${time.toLocaleString('en', { timeZone: 'America/New_York' })}`, '3:23:30 PM'));
it(`(${time.toString()}).toLocaleString('de-AT', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${time.toLocaleString('de', { timeZone: 'Europe/Vienna' })}`, '15:23:30'));
it('should ignore units not in the data type', () => {
equal(time.toLocaleString('en', { timeZoneName: 'long' }), '3:23:30 PM');
equal(time.toLocaleString('en', { year: 'numeric' }), '3:23:30 PM');
equal(time.toLocaleString('en', { month: 'numeric' }), '3:23:30 PM');
equal(time.toLocaleString('en', { day: 'numeric' }), '3:23:30 PM');
});
});
describe('date.toLocaleString()', () => {
const date = Temporal.Date.from('1976-11-18T15:23:30');
it(`(${date.toString()}).toLocaleString('en-US', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${date.toLocaleString('en', { timeZone: 'America/New_York' })}`, '11/18/1976'));
it(`(${date.toString()}).toLocaleString('de-AT', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${date.toLocaleString('de', { timeZone: 'Europe/Vienna' })}`, '18.11.1976'));
it('should ignore units not in the data type', () => {
equal(date.toLocaleString('en', { timeZoneName: 'long' }), '11/18/1976');
equal(date.toLocaleString('en', { hour: 'numeric' }), '11/18/1976');
equal(date.toLocaleString('en', { minute: 'numeric' }), '11/18/1976');
equal(date.toLocaleString('en', { second: 'numeric' }), '11/18/1976');
});
});
describe('yearmonth.toLocaleString()', () => {
const yearmonth = Temporal.YearMonth.from('1976-11-18T15:23:30');
it(`(${yearmonth.toString()}).toLocaleString('en-US', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${yearmonth.toLocaleString('en', { timeZone: 'America/New_York' })}`, '11/1976'));
it(`(${yearmonth.toString()}).toLocaleString('de-AT', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${yearmonth.toLocaleString('de', { timeZone: 'Europe/Vienna' })}`, '11.1976'));
it('should ignore units not in the data type', () => {
equal(yearmonth.toLocaleString('en', { timeZoneName: 'long' }), '11/1976');
equal(yearmonth.toLocaleString('en', { day: 'numeric' }), '11/1976');
equal(yearmonth.toLocaleString('en', { hour: 'numeric' }), '11/1976');
equal(yearmonth.toLocaleString('en', { minute: 'numeric' }), '11/1976');
equal(yearmonth.toLocaleString('en', { second: 'numeric' }), '11/1976');
});
});
describe('monthday.toLocaleString()', () => {
const monthday = Temporal.MonthDay.from('1976-11-18T15:23:30');
it(`(${monthday.toString()}).toLocaleString('en-US', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${monthday.toLocaleString('en', { timeZone: 'America/New_York' })}`, '11/18'));
it(`(${monthday.toString()}).toLocaleString('de-AT', { timeZone: 'Europe/Vienna' })`, () =>
equal(`${monthday.toLocaleString('de', { timeZone: 'Europe/Vienna' })}`, '18.11.'));
it('should ignore units not in the data type', () => {
equal(monthday.toLocaleString('en', { timeZoneName: 'long' }), '11/18');
equal(monthday.toLocaleString('en', { year: 'numeric' }), '11/18');
equal(monthday.toLocaleString('en', { hour: 'numeric' }), '11/18');
equal(monthday.toLocaleString('en', { minute: 'numeric' }), '11/18');
equal(monthday.toLocaleString('en', { second: 'numeric' }), '11/18');
});
});

describe('DateTimeFormat', () => {
Expand Down

0 comments on commit e534d27

Please sign in to comment.