feat(localize): add reusable generators for month and weekday names
This commit is contained in:
parent
97fe0f0aa7
commit
043106c1cf
5 changed files with 166 additions and 0 deletions
|
|
@ -1,5 +1,7 @@
|
|||
export { formatDate } from './src/date/formatDate.js';
|
||||
export { getDateFormatBasedOnLocale } from './src/date/getDateFormatBasedOnLocale.js';
|
||||
export { getMonthNames } from './src/date/getMonthNames.js';
|
||||
export { getWeekdayNames } from './src/date/getWeekdayNames.js';
|
||||
export { parseDate } from './src/date/parseDate.js';
|
||||
export {
|
||||
formatNumber,
|
||||
|
|
|
|||
25
packages/localize/src/date/getMonthNames.js
Normal file
25
packages/localize/src/date/getMonthNames.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { normalizeDate } from './normalizeDate.js';
|
||||
|
||||
const monthsLocaleCache = {};
|
||||
|
||||
export function getMonthNames({ locale }) {
|
||||
let months = monthsLocaleCache[locale];
|
||||
|
||||
if (months) {
|
||||
return months;
|
||||
}
|
||||
|
||||
months = [];
|
||||
|
||||
const formatter = new Intl.DateTimeFormat(locale, { month: 'long' });
|
||||
for (let i = 0; i < 12; i += 1) {
|
||||
const date = new Date(2019, i, 1);
|
||||
const formattedDate = formatter.format(date);
|
||||
const normalizedDate = normalizeDate(formattedDate);
|
||||
months.push(normalizedDate);
|
||||
}
|
||||
|
||||
monthsLocaleCache[locale] = months;
|
||||
|
||||
return months;
|
||||
}
|
||||
53
packages/localize/src/date/getWeekdayNames.js
Normal file
53
packages/localize/src/date/getWeekdayNames.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { normalizeDate } from './normalizeDate.js';
|
||||
|
||||
const weekdayNamesCache = {};
|
||||
|
||||
/**
|
||||
* @desc Return cached weekday names for locale for all styles ('long', 'short', 'narrow')
|
||||
* @param {string} locale locale
|
||||
* @returns {Object} like { long: ['Sunday', 'Monday'...], short: ['Sun', ...], narrow: ['S', ...] }
|
||||
*/
|
||||
function getCachedWeekdayNames(locale) {
|
||||
let weekdays = weekdayNamesCache[locale];
|
||||
|
||||
if (weekdays) {
|
||||
return weekdays;
|
||||
}
|
||||
|
||||
weekdayNamesCache[locale] = { long: [], short: [], narrow: [] };
|
||||
|
||||
['long', 'short', 'narrow'].forEach(style => {
|
||||
weekdays = weekdayNamesCache[locale][style];
|
||||
const formatter = new Intl.DateTimeFormat(locale, { weekday: style });
|
||||
|
||||
const date = new Date('2019/04/07'); // start from Sunday
|
||||
for (let i = 0; i < 7; i += 1) {
|
||||
const weekday = formatter.format(date);
|
||||
const normalizedWeekday = normalizeDate(weekday);
|
||||
weekdays.push(normalizedWeekday);
|
||||
date.setDate(date.getDate() + 1);
|
||||
}
|
||||
});
|
||||
|
||||
return weekdayNamesCache[locale];
|
||||
}
|
||||
|
||||
// TODO: consider using a database with information for the `firstDayOfWeek`?
|
||||
// https://github.com/unicode-cldr/cldr-core/blob/35.0.0/supplemental/weekData.json#L60
|
||||
// https://github.com/tc39/ecma402/issues/6#issuecomment-114079502
|
||||
|
||||
/**
|
||||
* @desc Returns weekday names for locale
|
||||
* @param {string} options.locale locale
|
||||
* @param {string} [options.style=long] long, short or narrow
|
||||
* @param {number} [options.firstDayOfWeek=0] 0 (Sunday), 1 (Monday), etc...
|
||||
* @returns {Array} like: ['Sunday', 'Monday', 'Tuesday', ...etc].
|
||||
*/
|
||||
export function getWeekdayNames({ locale, style = 'long', firstDayOfWeek = 0 } = {}) {
|
||||
const weekdays = getCachedWeekdayNames(locale)[style];
|
||||
const orderedWeekdays = [];
|
||||
for (let i = firstDayOfWeek; i < firstDayOfWeek + 7; i += 1) {
|
||||
orderedWeekdays.push(weekdays[i % 7]);
|
||||
}
|
||||
return orderedWeekdays;
|
||||
}
|
||||
21
packages/localize/test/date/getMonthNames.test.js
Normal file
21
packages/localize/test/date/getMonthNames.test.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { expect } from '@open-wc/testing';
|
||||
|
||||
import { getMonthNames } from '../../src/date/getMonthNames.js';
|
||||
|
||||
function s(strings) {
|
||||
return strings[0].split(' ');
|
||||
}
|
||||
|
||||
describe('getMonthNames', () => {
|
||||
it('generates month names for a given locale', () => {
|
||||
expect(getMonthNames({ locale: 'en-GB' })).to.deep.equal(
|
||||
s`January February March April May June July August September October November December`,
|
||||
);
|
||||
expect(getMonthNames({ locale: 'nl-NL' })).to.deep.equal(
|
||||
s`januari februari maart april mei juni juli augustus september oktober november december`,
|
||||
);
|
||||
expect(getMonthNames({ locale: 'zh-CH' })).to.deep.equal(
|
||||
s`一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月`,
|
||||
);
|
||||
});
|
||||
});
|
||||
65
packages/localize/test/date/getWeekdayNames.test.js
Normal file
65
packages/localize/test/date/getWeekdayNames.test.js
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { expect } from '@open-wc/testing';
|
||||
|
||||
import { getWeekdayNames } from '../../src/date/getWeekdayNames.js';
|
||||
|
||||
function s(strings) {
|
||||
return strings[0].split(' ');
|
||||
}
|
||||
|
||||
describe('getWeekdayNames', () => {
|
||||
it('generates weekday names for a given locale with defaults (from Sunday, long style)', () => {
|
||||
expect(getWeekdayNames({ locale: 'en-GB' })).to.deep.equal(
|
||||
s`Sunday Monday Tuesday Wednesday Thursday Friday Saturday`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'nl-NL' })).to.deep.equal(
|
||||
s`zondag maandag dinsdag woensdag donderdag vrijdag zaterdag`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'zh-CH' })).to.deep.equal(
|
||||
s`星期日 星期一 星期二 星期三 星期四 星期五 星期六`,
|
||||
);
|
||||
});
|
||||
|
||||
it('allows to specify a day when a week starts', () => {
|
||||
expect(getWeekdayNames({ locale: 'en-GB', firstDayOfWeek: 7 })).to.deep.equal(
|
||||
s`Sunday Monday Tuesday Wednesday Thursday Friday Saturday`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'en-GB', firstDayOfWeek: 1 })).to.deep.equal(
|
||||
s`Monday Tuesday Wednesday Thursday Friday Saturday Sunday`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'en-GB', firstDayOfWeek: 2 })).to.deep.equal(
|
||||
s`Tuesday Wednesday Thursday Friday Saturday Sunday Monday`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'en-GB', firstDayOfWeek: 3 })).to.deep.equal(
|
||||
s`Wednesday Thursday Friday Saturday Sunday Monday Tuesday`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'en-GB', firstDayOfWeek: 4 })).to.deep.equal(
|
||||
s`Thursday Friday Saturday Sunday Monday Tuesday Wednesday`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'en-GB', firstDayOfWeek: 5 })).to.deep.equal(
|
||||
s`Friday Saturday Sunday Monday Tuesday Wednesday Thursday`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'en-GB', firstDayOfWeek: 6 })).to.deep.equal(
|
||||
s`Saturday Sunday Monday Tuesday Wednesday Thursday Friday`,
|
||||
);
|
||||
});
|
||||
|
||||
it('supports "short" style', () => {
|
||||
expect(getWeekdayNames({ locale: 'en-GB', style: 'short' })).to.deep.equal(
|
||||
s`Sun Mon Tue Wed Thu Fri Sat`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'nl-NL', style: 'short' })).to.deep.equal(
|
||||
s`zo ma di wo do vr za`,
|
||||
);
|
||||
expect(getWeekdayNames({ locale: 'zh-CH', style: 'short' })).to.deep.equal(
|
||||
s`周日 周一 周二 周三 周四 周五 周六`,
|
||||
);
|
||||
});
|
||||
|
||||
it('supports "narrow" style', () => {
|
||||
expect(getWeekdayNames({ locale: 'en-GB', style: 'narrow' })).to.deep.equal(s`S M T W T F S`);
|
||||
expect(getWeekdayNames({ locale: 'nl-NL', style: 'narrow' })).to.deep.equal(s`Z M D W D V Z`);
|
||||
expect(getWeekdayNames({ locale: 'zh-CH', style: 'narrow' })).to.deep.equal(
|
||||
s`日 一 二 三 四 五 六`,
|
||||
);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue