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 { formatDate } from './src/date/formatDate.js';
|
||||||
export { getDateFormatBasedOnLocale } from './src/date/getDateFormatBasedOnLocale.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 { parseDate } from './src/date/parseDate.js';
|
||||||
export {
|
export {
|
||||||
formatNumber,
|
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