-
-
Notifications
You must be signed in to change notification settings - Fork 338
Expand file tree
/
Copy pathluxon.ts
More file actions
135 lines (116 loc) Β· 4.18 KB
/
luxon.ts
File metadata and controls
135 lines (116 loc) Β· 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { DateTime, Info } from 'luxon';
import type { GenerateConfig } from '.';
const weekDayFormatMap = {
zh_CN: 'narrow',
zh_TW: 'narrow',
};
const weekDayLengthMap = {
en_US: 2,
en_GB: 2,
};
/**
* Normalizes part of a moment format string that should
* not be escaped to a luxon compatible format string.
*
* @param part string
* @returns string
*/
const normalizeFormatPart = (part: string): string =>
part
.replace(/Y/g, 'y')
.replace(/D/g, 'd')
.replace(/gg/g, 'kk')
.replace(/Q/g, 'q')
.replace(/([Ww])o/g, 'WW');
/**
* Normalizes a moment compatible format string to a luxon compatible format string
*
* @param format string
* @returns string
*/
const normalizeFormat = (format: string): string =>
format
// moment escapes strings contained in brackets
.split(/[[\]]/)
.map((part, index) => {
const shouldEscape = index % 2 > 0;
return shouldEscape ? part : normalizeFormatPart(part);
})
// luxon escapes strings contained in single quotes
.join("'");
/**
* Normalizes language tags used to luxon compatible
* language tags by replacing underscores with hyphen-minus.
*
* @param locale string
* @returns string
*/
const normalizeLocale = (locale: string): string => locale.replace(/_/g, '-');
const getGenerateConfig = (useLocaleWeeks?: boolean): GenerateConfig<DateTime> => ({
// get
getNow: () => DateTime.local(),
getFixedDate: (string) => DateTime.fromFormat(string, 'yyyy-MM-dd'),
getEndDate: (date) => date.endOf('month'),
getWeekDay: (date) => date.weekday,
getYear: (date) => date.year,
getMonth: (date) => date.month - 1, // getMonth should return 0-11, luxon month returns 1-12
getDate: (date) => date.day,
getHour: (date) => date.hour,
getMinute: (date) => date.minute,
getSecond: (date) => date.second,
getMillisecond: (date) => date.millisecond,
// set
addYear: (date, diff) => date.plus({ year: diff }),
addMonth: (date, diff) => date.plus({ month: diff }),
addDate: (date, diff) => date.plus({ day: diff }),
setYear: (date, year) => date.set({ year }),
setMonth: (date, month) => date.set({ month: month + 1 }), // setMonth month argument is 0-11, luxon months are 1-12
setDate: (date, day) => date.set({ day }),
setHour: (date, hour) => date.set({ hour }),
setMinute: (date, minute) => date.set({ minute }),
setSecond: (date, second) => date.set({ second }),
setMillisecond: (date, milliseconds) => date.set({ millisecond: milliseconds }),
// Compare
isAfter: (date1, date2) => date1 > date2,
isValidate: (date) => date.isValid,
locale: {
getWeekFirstDate: (locale, date) =>
date.setLocale(normalizeLocale(locale)).startOf('week', { useLocaleWeeks }),
getWeekFirstDay: (locale) =>
DateTime.local().setLocale(normalizeLocale(locale)).startOf('week', { useLocaleWeeks })
.weekday,
getWeek: (locale, date) => date.setLocale(normalizeLocale(locale)).weekNumber,
getShortWeekDays: (locale) => {
const weekdays = Info.weekdays(weekDayFormatMap[locale] || 'short', {
locale: normalizeLocale(locale),
});
const shifted = weekdays.map((weekday) => weekday.slice(0, weekDayLengthMap[locale]));
// getShortWeekDays should return weekday labels starting from Sunday.
// luxon returns them starting from Monday, so we have to shift the results.
shifted.unshift(shifted.pop() as string);
return shifted;
},
getShortMonths: (locale) => Info.months('short', { locale: normalizeLocale(locale) }),
format: (locale, date, format) => {
if (!date || !date.isValid) {
return null;
}
return date.setLocale(normalizeLocale(locale)).toFormat(normalizeFormat(format));
},
parse: (locale, text, formats) => {
for (let i = 0; i < formats.length; i += 1) {
const normalizedFormat = normalizeFormat(formats[i]);
const date = DateTime.fromFormat(text, normalizedFormat, {
locale: normalizeLocale(locale),
});
if (date.isValid) {
return date;
}
}
return null;
},
},
});
const generateConfig = getGenerateConfig();
export const generateConfigWithLocale = getGenerateConfig(true);
export default generateConfig;