@variantjs/core
Version:
VariantJS common functions and utilities
142 lines (108 loc) • 3.83 kB
text/typescript
import { DateLocale, TokenFormattingFunctions, DateToken } from '../types/Dates';
import { English } from './l10n/default';
const boolToInt = (bool: boolean) : 1 | 0 => (bool === true ? 1 : 0);
const pad = (number: string | number, length = 2) : string => `000${number}`.slice(length * -1);
const monthToString = (
monthNumber: number,
shorthand: boolean,
locale: DateLocale,
): string => locale.months[shorthand ? 'shorthand' : 'longhand'][monthNumber];
export const tokenFormatingFunctions: TokenFormattingFunctions = {
// get the date in UTC
Z: (date: Date) => date.toISOString(),
// weekday name, short, e.g. Thu
D(date: Date, locale: DateLocale) {
return locale.weekdays.shorthand[
tokenFormatingFunctions.w(date, locale) as number
];
},
// full month name e.g. January
F(date: Date, locale: DateLocale) {
return monthToString(
(tokenFormatingFunctions.n(date, locale) as number) - 1,
false,
locale,
);
},
// padded hour 1-12
G(date: Date, locale: DateLocale) {
return pad(tokenFormatingFunctions.h(date, locale));
},
// hours with leading zero e.g. 03
H: (date: Date) => pad(date.getHours()),
// day (1-30) with ordinal suffix e.g. 1st, 2nd
J(date: Date, locale: DateLocale) {
return date.getDate() + locale.ordinal(date.getDate());
},
// AM/PM
K: (date: Date, locale: DateLocale) => locale.amPM[boolToInt(date.getHours() > 11)],
// shorthand month e.g. Jan, Sep, Oct, etc
M(date: Date, locale: DateLocale) {
return monthToString(date.getMonth(), true, locale);
},
// seconds 00-59
S: (date: Date) => pad(date.getSeconds()),
// unix timestamp
U: (date: Date) => date.getTime() / 1000,
W(givenDate: Date) {
// return options.getWeek(date);
const date = new Date(givenDate.getTime());
date.setHours(0, 0, 0, 0);
// Thursday in current week decides the year.
date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));
// January 4 is always in week 1.
const week1 = new Date(date.getFullYear(), 0, 4);
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
return (
1
+ Math.round(
((date.getTime() - week1.getTime()) / 86400000
- 3
+ ((week1.getDay() + 6) % 7))
/ 7,
)
);
},
// full year e.g. 2016, padded (0001-9999)
Y: (date: Date) => pad(date.getFullYear(), 4),
// day in month, padded (01-30)
d: (date: Date) => pad(date.getDate()),
// hour from 1-12 (am/pm)
h: (date: Date) => (date.getHours() % 12 ? date.getHours() % 12 : 12),
// minutes, padded with leading zero e.g. 09
i: (date: Date) => pad(date.getMinutes()),
// day in month (1-30)
j: (date: Date) => date.getDate(),
// weekday name, full, e.g. Thursday
l(date: Date, locale: DateLocale) {
return locale.weekdays.longhand[date.getDay()];
},
// padded month number (01-12)
m: (date: Date) => pad(date.getMonth() + 1),
// the month number (1-12)
n: (date: Date) => date.getMonth() + 1,
// seconds 0-59
s: (date: Date) => date.getSeconds(),
// number of the day of the week
w: (date: Date) => date.getDay(),
// last two digits of year e.g. 16 for 2016
y: (date: Date) => String(date.getFullYear()).substring(2),
};
const formatDate = (date: Date | null | undefined, format: string, customLocale?: DateLocale): string => {
if (!date) {
return '';
}
const locale = customLocale || English;
return format
.split('')
.map((char, i, arr) => {
if (tokenFormatingFunctions[char as DateToken] && arr[i - 1] !== '\\') {
return tokenFormatingFunctions[char as DateToken](date, locale);
} if (char !== '\\') {
return char;
}
return '';
})
.join('');
};
export default formatDate;