nemoin
Version:
Typescript Date library
108 lines (89 loc) • 4.7 kB
text/typescript
import {createFormat} from '../../src/format/create-format';
import {createParse, parseOrThrowWrapper} from '../../src/parse/create-parse';
import defaultFormatters from '../../src/format/default-formatters';
import defaultParsers from '../../src/parse/default-parsers';
import {ParserObj, FormatterObj, FormatByTemplateFn, ParseByTemplateFn, ParseByTemplateOrThrowFn, ParserData} from '../../src/utils/basic-types';
import {extend} from '../../src/utils/utils';
export * from '../../src/default-exports';
// http://new.gramota.ru/spravka/buro/search-answer?s=242637
const monthsShort = ['янв.', 'фев.', 'март', 'апр.', 'май', 'июнь', 'июль', 'авг.', 'сент.', 'окт.', 'нояб.', 'дек.'];
const monthsFull = ['январь', 'февраль', 'март', 'апрель', 'май', 'июнь', 'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'];
const monthsGenitive = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'];
const weekdays2char = ['вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'];
const weekdays3char = ['вск', 'пнд', 'втр', 'срд', 'чтв', 'птн', 'суб'];
const weekdaysFull = ['воскресенье', 'понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота'];
const meridiem = ['ночи', 'утра', 'дня', 'вечера'];
const formatters: FormatterObj = {
// Month: янв., фев., ..., дек.
'MMM': date => monthsShort[date.getMonth()],
// Month: январь, февраль, ..., декабрь
'MMMM': (date, index, tokens) => {
const month = date.getMonth();
if (tokens === undefined || index === undefined || index < 2) return monthsFull[month];
const prevToken = tokens[index - 2];
if (typeof tokens[index - 1] === 'string' && prevToken === defaultFormatters.D || prevToken === defaultFormatters.DD) {
// Generate formatters like 'D[some string]MMMM',
// where month is in the genitive case: января, февраля, ..., декабря
return monthsGenitive[month];
}
return monthsFull[month];
},
// Day of week: вс, пн, ..., сб
'dd': date => weekdays2char[date.getDay()],
// Day of week: вск, пнд, ..., суб
'ddd': date => weekdays3char[date.getDay()],
// Day of week: воскресенье, понедельник, ..., суббота
'dddd': date => weekdaysFull[date.getDay()],
// Time of day: ночи, утра, дня, вечера
'A': date => {
const hours = date.getHours();
if (hours >= 17) {
return meridiem[3];
} else if (hours >= 12) {
return meridiem[2];
} else if (hours >= 4) {
return meridiem[1];
} else {
return meridiem[0];
}
},
// Generate ordinal version of formatters: M -> Mo, DDD -> DDDo, etc.
'Do': date => defaultFormatters['D'](date) + '-е',
'Wo': date => defaultFormatters['W'](date) + '-й',
'Mo': date => defaultFormatters['M'](date) + '-й',
'DDDo': date => defaultFormatters['DDD'](date) + '-й',
'do': date => defaultFormatters['d'](date) + '-й',
'Qo': date => defaultFormatters['Q'](date) + '-й',
'Do MMMM': date => formatters['Do'](date) + ' ' + monthsGenitive[date.getMonth()]
};
formatters['a'] = formatters['aa'] = formatters['A'];
const parsers: ParserObj = {
// Month: янв., фев., ..., дек.
'MMM': [monthsShort.join('|'), (date, value) => {
const index = monthsShort.indexOf(value.toLowerCase());
date.setMonth(index);
}],
// Month: январь, февраль, ..., декабрь
// ... января, февраля, ..., декабря
'MMMM': [monthsFull.concat(monthsGenitive).join('|'), (date, value) => {
value = value.toLowerCase();
let index = monthsFull.indexOf(value);
if (index < 0) index = monthsGenitive.indexOf(value);
date.setMonth(index);
}],
// Generate ordinal version of parsers by cutting the suffix
'Do': ordinalParser('D', '-е'),
'Wo': ordinalParser('W', '-й'),
'Mo': ordinalParser('M', '-й'),
'DDDo': ordinalParser('DDD', '-й'),
'do': ordinalParser('d', '-й'),
'Qo': ordinalParser('Q', '-й'),
};
function ordinalParser(key: string, suffix: string): ParserData {
return ['\\d+' + suffix, (date, value) => {
defaultParsers[key][1](date, value.slice(0, -suffix.length));
}];
}
export const format: FormatByTemplateFn = createFormat(extend(defaultFormatters, formatters));
export const parse: ParseByTemplateFn = createParse(extend(defaultParsers, parsers));
export const parseOrThrow: ParseByTemplateOrThrowFn = parseOrThrowWrapper(parse);