@central-design-system/components 3.0.0-alpha.2 → 3.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cds.css +1 -1
- package/dist/cds.es.js +101 -101
- package/dist/cds.umd.js +1 -1
- package/dist/components/CdsCheckbox/CdsCheckbox.vue.d.ts +20 -4
- package/dist/components/CdsCombobox/CdsCombobox.vue.d.ts +125 -64
- package/dist/components/CdsDatePicker/CdsDatePicker.vue.d.ts +35 -5
- package/dist/components/CdsDrawer/CdsDrawer.vue.d.ts +20 -4
- package/dist/components/CdsDropdown/CdsDropdown.vue.d.ts +133 -116
- package/dist/components/CdsForm/CdsForm.vue.d.ts +13 -3
- package/dist/components/CdsInput/CdsInput.vue.d.ts +8 -2
- package/dist/components/CdsLink/CdsLink.vue.d.ts +9 -2
- package/dist/components/CdsList/CdsList.vue.d.ts +46 -13
- package/dist/components/CdsList/CdsListItem.vue.d.ts +8 -2
- package/dist/components/CdsMenu/CdsMenu.vue.d.ts +16 -6
- package/dist/components/CdsOverlay/CdsOverlay.vue.d.ts +20 -10
- package/dist/components/CdsRadioButton/CdsRadio.vue.d.ts +9 -3
- package/dist/components/CdsRadioButton/CdsRadioButton.vue.d.ts +9 -3
- package/dist/components/CdsSelect/CdsSelect.vue.d.ts +57 -36
- package/dist/components/CdsSidebar/CdsSidebar.vue.d.ts +14 -4
- package/dist/components/CdsTag/CdsTag.vue.d.ts +9 -2
- package/dist/components/CdsTextArea/CdsTextArea.vue.d.ts +63 -21
- package/dist/components/CdsTextInput/CdsTextInput.vue.d.ts +91 -26
- package/package.json +3 -2
- package/src/scss/themes/index.ts +1 -1
- package/src/utils/__test__/helper.test.ts +59 -0
- package/src/utils/__test__/mocks/helper.mock.ts +362 -0
- package/src/utils/__test__/mocks/propFactory.mock.ts +88 -0
- package/src/utils/__test__/propFactory.test.ts +9 -0
- package/src/utils/anchor.ts +76 -0
- package/src/utils/animation.ts +62 -0
- package/src/utils/box.ts +39 -0
- package/src/utils/cache.ts +12 -0
- package/src/utils/changeCase/__test__/lowerCase.test.ts +12 -0
- package/src/utils/changeCase/__test__/mocks/lowerCase.mock.ts +80 -0
- package/src/utils/changeCase/__test__/mocks/noCase.mock.ts +131 -0
- package/src/utils/changeCase/__test__/mocks/paramCase.mock.ts +39 -0
- package/src/utils/changeCase/__test__/mocks/pascalCase.mock.ts +46 -0
- package/src/utils/changeCase/__test__/noCase.test.ts +8 -0
- package/src/utils/changeCase/__test__/paramCase.test.ts +8 -0
- package/src/utils/changeCase/__test__/pascalCase.test.ts +8 -0
- package/src/utils/changeCase/lowerCase.ts +56 -0
- package/src/utils/changeCase/noCase.ts +45 -0
- package/src/utils/changeCase/paramCase.ts +11 -0
- package/src/utils/changeCase/pascalCase.ts +24 -0
- package/src/utils/date.ts +1100 -0
- package/src/utils/dom.ts +24 -0
- package/src/utils/getCurrentInstance.ts +43 -0
- package/src/utils/getScrollParent.ts +29 -0
- package/src/utils/globals.ts +8 -0
- package/src/utils/helpers.ts +311 -0
- package/src/utils/index.ts +19 -0
- package/src/utils/propsFactory.ts +92 -0
|
@@ -0,0 +1,1100 @@
|
|
|
1
|
+
import { isDate, pad } from '@components/utils';
|
|
2
|
+
import defaultLang from '@components/locale/ru';
|
|
3
|
+
|
|
4
|
+
import type { ILocale } from '@components/locale';
|
|
5
|
+
|
|
6
|
+
export interface IRawDate {
|
|
7
|
+
year?: number;
|
|
8
|
+
month?: number;
|
|
9
|
+
day?: number;
|
|
10
|
+
hour?: number;
|
|
11
|
+
minute?: number;
|
|
12
|
+
second?: number;
|
|
13
|
+
millisecond?: number;
|
|
14
|
+
timezoneOffset?: number;
|
|
15
|
+
dateHash?: string;
|
|
16
|
+
timeHash?: string;
|
|
17
|
+
date?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type TDateLocale = ILocale['date'];
|
|
21
|
+
|
|
22
|
+
const MILLISECONDS_IN_DAY: number = 86400000;
|
|
23
|
+
const MILLISECONDS_IN_HOUR: number = 3600000;
|
|
24
|
+
const MILLISECONDS_IN_MINUTE: number = 60000;
|
|
25
|
+
const defaultMask: string = 'YYYY-MM-DDTHH:mm:ss.SSSZ';
|
|
26
|
+
const token: RegExp =
|
|
27
|
+
/\[((?:[^\]\\]|\\]|\\)*)\]|d{1,4}|M{1,4}|m{1,2}|w{1,2}|Qo|Do|D{1,4}|YY(?:YY)?|H{1,2}|h{1,2}|s{1,2}|S{1,3}|Z{1,2}|a{1,2}|[AQExX]/g;
|
|
28
|
+
const reverseToken: RegExp =
|
|
29
|
+
/(\[[^\]]*\])|d{1,4}|M{1,4}|m{1,2}|w{1,2}|Qo|Do|D{1,4}|YY(?:YY)?|H{1,2}|h{1,2}|s{1,2}|S{1,3}|Z{1,2}|a{1,2}|[AQExX]|([.*+:?^,\s${}()|\\]+)/g;
|
|
30
|
+
const regexStore: Record<string, any> = {};
|
|
31
|
+
|
|
32
|
+
const formatter: Record<string, Function> = {
|
|
33
|
+
// Year: 00, 01, ..., 99
|
|
34
|
+
YY(date: Date, dateLocale: TDateLocale, forcedYear: number) {
|
|
35
|
+
// workaround for < 1900 with new Date()
|
|
36
|
+
const y = this.YYYY(date, dateLocale, forcedYear) % 100;
|
|
37
|
+
return y >= 0 ? pad(y) : '-' + pad(Math.abs(y));
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
// Year: 1900, 1901, ..., 2099
|
|
41
|
+
YYYY(date: Date, _dateLocale: TDateLocale, forcedYear: number) {
|
|
42
|
+
// workaround for < 1900 with new Date()
|
|
43
|
+
return forcedYear !== void 0 && forcedYear !== null ? forcedYear : date.getFullYear();
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
// Month: 1, 2, ..., 12
|
|
47
|
+
M(date: Date) {
|
|
48
|
+
return date.getMonth() + 1;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
// Month: 01, 02, ..., 12
|
|
52
|
+
MM(date: Date) {
|
|
53
|
+
return pad(date.getMonth() + 1);
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
// Month Short Name: Jan, Feb, ...
|
|
57
|
+
MMM(date: Date, dateLocale: TDateLocale) {
|
|
58
|
+
return dateLocale.monthsShort[date.getMonth()];
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// Month Name: January, February, ...
|
|
62
|
+
MMMM(date: Date, dateLocale: TDateLocale) {
|
|
63
|
+
return dateLocale.months[date.getMonth()];
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
// Quarter: 1, 2, 3, 4
|
|
67
|
+
Q(date: Date) {
|
|
68
|
+
return Math.ceil((date.getMonth() + 1) / 3);
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
// Quarter: 1st, 2nd, 3rd, 4th
|
|
72
|
+
Qo(date: Date) {
|
|
73
|
+
return getOrdinal(this.Q(date));
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// Day of month: 1, 2, ..., 31
|
|
77
|
+
D(date: Date) {
|
|
78
|
+
return date.getDate();
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
// Day of month: 1st, 2nd, ..., 31st
|
|
82
|
+
Do(date: Date) {
|
|
83
|
+
return getOrdinal(date.getDate());
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// Day of month: 01, 02, ..., 31
|
|
87
|
+
DD(date: Date) {
|
|
88
|
+
return pad(date.getDate());
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Day of year: 1, 2, ..., 366
|
|
92
|
+
DDD(date: Date) {
|
|
93
|
+
return getDayOfYear(date);
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
// Day of year: 001, 002, ..., 366
|
|
97
|
+
DDDD(date: Date) {
|
|
98
|
+
return pad(getDayOfYear(date) as number, 3);
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
// Day of week: 0, 1, ..., 6
|
|
102
|
+
d(date: Date) {
|
|
103
|
+
return date.getDay();
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
// Day of week: Su, Mo, ...
|
|
107
|
+
dd(date: Date, dateLocale: TDateLocale) {
|
|
108
|
+
return this.dddd(date, dateLocale).slice(0, 2);
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// Day of week: Sun, Mon, ...
|
|
112
|
+
ddd(date: Date, dateLocale: TDateLocale) {
|
|
113
|
+
return dateLocale.daysShort[date.getDay()];
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
// Day of week: Sunday, Monday, ...
|
|
117
|
+
dddd(date: Date, dateLocale: TDateLocale) {
|
|
118
|
+
return dateLocale.days[date.getDay()];
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// Day of ISO week: 1, 2, ..., 7
|
|
122
|
+
E(date: Date) {
|
|
123
|
+
return date.getDay() || 7;
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
// Week of Year: 1 2 ... 52 53
|
|
127
|
+
w(date: Date) {
|
|
128
|
+
return getWeekOfYear(date);
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// Week of Year: 01 02 ... 52 53
|
|
132
|
+
ww(date: Date) {
|
|
133
|
+
return pad(getWeekOfYear(date));
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
// Hour: 0, 1, ... 23
|
|
137
|
+
H(date: Date) {
|
|
138
|
+
return date.getHours();
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
// Hour: 00, 01, ..., 23
|
|
142
|
+
HH(date: Date) {
|
|
143
|
+
return pad(date.getHours());
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
// Hour: 1, 2, ..., 12
|
|
147
|
+
h(date: Date) {
|
|
148
|
+
const hours = date.getHours();
|
|
149
|
+
return hours === 0 ? 12 : hours > 12 ? hours % 12 : hours;
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
// Hour: 01, 02, ..., 12
|
|
153
|
+
hh(date: Date) {
|
|
154
|
+
return pad(this.h(date));
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
// Minute: 0, 1, ..., 59
|
|
158
|
+
m(date: Date) {
|
|
159
|
+
return date.getMinutes();
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// Minute: 00, 01, ..., 59
|
|
163
|
+
mm(date: Date) {
|
|
164
|
+
return pad(date.getMinutes());
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
// Second: 0, 1, ..., 59
|
|
168
|
+
s(date: Date) {
|
|
169
|
+
return date.getSeconds();
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// Second: 00, 01, ..., 59
|
|
173
|
+
ss(date: Date) {
|
|
174
|
+
return pad(date.getSeconds());
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
// 1/10 of second: 0, 1, ..., 9
|
|
178
|
+
S(date: Date) {
|
|
179
|
+
return Math.floor(date.getMilliseconds() / 100);
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
// 1/100 of second: 00, 01, ..., 99
|
|
183
|
+
SS(date: Date) {
|
|
184
|
+
return pad(Math.floor(date.getMilliseconds() / 10));
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// Millisecond: 000, 001, ..., 999
|
|
188
|
+
SSS(date: Date) {
|
|
189
|
+
return pad(date.getMilliseconds(), 3);
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
// Meridiem: AM, PM
|
|
193
|
+
A(date: Date) {
|
|
194
|
+
return this.H(date) < 12 ? 'AM' : 'PM';
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
// Meridiem: am, pm
|
|
198
|
+
a(date: Date) {
|
|
199
|
+
return this.H(date) < 12 ? 'am' : 'pm';
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
// Meridiem: a.m., p.m.
|
|
203
|
+
aa(date: Date) {
|
|
204
|
+
return this.H(date) < 12 ? 'a.m.' : 'p.m.';
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
// Timezone: -01:00, +00:00, ... +12:00
|
|
208
|
+
Z(date: Date, _dateLocale: TDateLocale, _forcedYear: number, forcedTimezoneOffset: number) {
|
|
209
|
+
const tzOffset =
|
|
210
|
+
forcedTimezoneOffset === void 0 || forcedTimezoneOffset === null
|
|
211
|
+
? date.getTimezoneOffset()
|
|
212
|
+
: forcedTimezoneOffset;
|
|
213
|
+
|
|
214
|
+
return formatTimezone(tzOffset, ':');
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
// Timezone: -0100, +0000, ... +1200
|
|
218
|
+
ZZ(date: Date, _dateLocale: TDateLocale, _forcedYear: number, forcedTimezoneOffset: number) {
|
|
219
|
+
const tzOffset =
|
|
220
|
+
forcedTimezoneOffset === void 0 || forcedTimezoneOffset === null
|
|
221
|
+
? date.getTimezoneOffset()
|
|
222
|
+
: forcedTimezoneOffset;
|
|
223
|
+
|
|
224
|
+
return formatTimezone(tzOffset);
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
// Seconds timestamp: 512969520
|
|
228
|
+
X(date: Date) {
|
|
229
|
+
return Math.floor(date.getTime() / 1000);
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
// Milliseconds timestamp: 512969520900
|
|
233
|
+
x(date: Date) {
|
|
234
|
+
return date.getTime();
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Format date by mask
|
|
240
|
+
* @param value
|
|
241
|
+
* @param mask
|
|
242
|
+
* @param dateLocale
|
|
243
|
+
* @param __forcedYear
|
|
244
|
+
* @param __forcedTimezoneOffset
|
|
245
|
+
*/
|
|
246
|
+
export function formatDate(
|
|
247
|
+
value: any,
|
|
248
|
+
mask: string,
|
|
249
|
+
dateLocale: TDateLocale,
|
|
250
|
+
__forcedYear: number,
|
|
251
|
+
__forcedTimezoneOffset: number
|
|
252
|
+
): string | undefined {
|
|
253
|
+
if ((value !== 0 && !value) || value === Infinity || value === -Infinity) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const date = new Date(value) as unknown as number;
|
|
258
|
+
|
|
259
|
+
if (isNaN(date)) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (mask === void 0) {
|
|
264
|
+
mask = defaultMask;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const locale = getDateLocale(dateLocale, defaultLang);
|
|
268
|
+
|
|
269
|
+
return mask.replace(token, (match, text) =>
|
|
270
|
+
match in formatter
|
|
271
|
+
? formatter[match](date, locale, __forcedYear, __forcedTimezoneOffset)
|
|
272
|
+
: text === void 0
|
|
273
|
+
? match
|
|
274
|
+
: text.split('\\]').join(']')
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Set a specific year, month and day to a date.
|
|
280
|
+
* @param date
|
|
281
|
+
* @param rawModified
|
|
282
|
+
* @param utc
|
|
283
|
+
*/
|
|
284
|
+
export function adjustDate(date: Date, rawModified: IRawDate, utc: boolean) {
|
|
285
|
+
const modified = normalizeModified(rawModified);
|
|
286
|
+
const middle = utc ? 'UTC' : '';
|
|
287
|
+
const _date = new Date(date);
|
|
288
|
+
const adjustedDate =
|
|
289
|
+
modified.year || modified.month || modified.date ? applyYearMonthDay(_date, modified, middle) : _date;
|
|
290
|
+
|
|
291
|
+
for (const key in modified) {
|
|
292
|
+
const op = key.charAt(0).toUpperCase() + key.slice(1);
|
|
293
|
+
(adjustedDate as Date & Record<string, any>)[`set${middle}${op}`](modified[key]);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return adjustedDate;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Parse any string into a date object based on the format passed.
|
|
301
|
+
* @param str
|
|
302
|
+
* @param mask
|
|
303
|
+
* @param dateLocale
|
|
304
|
+
*/
|
|
305
|
+
export function extractDate(str: string, mask: string, dateLocale: TDateLocale) {
|
|
306
|
+
const sDate = splitDate(str, mask, dateLocale);
|
|
307
|
+
|
|
308
|
+
const date = new Date(
|
|
309
|
+
sDate.year as number,
|
|
310
|
+
(sDate.month ? sDate.month - 1 : null) as number,
|
|
311
|
+
sDate.day ? sDate.day : 1,
|
|
312
|
+
sDate.hour,
|
|
313
|
+
sDate.minute,
|
|
314
|
+
sDate.second,
|
|
315
|
+
sDate.millisecond
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
const tzOffset = date.getTimezoneOffset();
|
|
319
|
+
|
|
320
|
+
return !sDate.timezoneOffset || sDate.timezoneOffset === tzOffset
|
|
321
|
+
? date
|
|
322
|
+
: getChange(date, { minutes: sDate.timezoneOffset - tzOffset }, 1);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Split date by mask.
|
|
327
|
+
* @param str
|
|
328
|
+
* @param mask
|
|
329
|
+
* @param dateLocale
|
|
330
|
+
* @param defaultModel
|
|
331
|
+
*/
|
|
332
|
+
export function splitDate(str: string, mask: string, dateLocale: TDateLocale, defaultModel?: IRawDate): IRawDate {
|
|
333
|
+
const date: IRawDate | Record<string, number | string | null> = {
|
|
334
|
+
year: null,
|
|
335
|
+
month: null,
|
|
336
|
+
day: null,
|
|
337
|
+
hour: null,
|
|
338
|
+
minute: null,
|
|
339
|
+
second: null,
|
|
340
|
+
millisecond: null,
|
|
341
|
+
timezoneOffset: null,
|
|
342
|
+
dateHash: null,
|
|
343
|
+
timeHash: null
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
defaultModel !== undefined && Object.assign(date, defaultModel);
|
|
347
|
+
|
|
348
|
+
if (str === undefined || str === null || str === '') return date;
|
|
349
|
+
|
|
350
|
+
if (!mask) mask = defaultMask;
|
|
351
|
+
|
|
352
|
+
const langOpts = getDateLocale(dateLocale, defaultLang);
|
|
353
|
+
const months = langOpts.months;
|
|
354
|
+
const monthsShort = langOpts.monthsShort;
|
|
355
|
+
|
|
356
|
+
const { regex, map } = getRegexData(mask, langOpts);
|
|
357
|
+
const match = str.match(regex);
|
|
358
|
+
|
|
359
|
+
if (match === null) return date;
|
|
360
|
+
|
|
361
|
+
let tzString = '';
|
|
362
|
+
|
|
363
|
+
if (map.X || map.x) {
|
|
364
|
+
const stamp = parseInt(match[map.X ? map.X : map.x], 10);
|
|
365
|
+
|
|
366
|
+
if (isNaN(stamp) || stamp < 0) return date;
|
|
367
|
+
|
|
368
|
+
const _date = new Date(stamp * (map.X ? 1000 : 0));
|
|
369
|
+
|
|
370
|
+
date.year = _date.getFullYear();
|
|
371
|
+
date.month = _date.getMonth() + 1;
|
|
372
|
+
date.date = _date.getDate();
|
|
373
|
+
date.hour = _date.getHours();
|
|
374
|
+
date.minute = _date.getMinutes();
|
|
375
|
+
date.second = _date.getSeconds();
|
|
376
|
+
date.millisecond = _date.getMilliseconds();
|
|
377
|
+
} else {
|
|
378
|
+
if (map.YYYY) {
|
|
379
|
+
date.year = parseInt(match[map.YYYY], 10);
|
|
380
|
+
} else if (map.YY) {
|
|
381
|
+
const year = parseInt(match[map.YY], 10);
|
|
382
|
+
date.year = year < 0 ? year : 2000 + year;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (map.M) {
|
|
386
|
+
date.month = parseInt(match[map.M], 10);
|
|
387
|
+
if (date.month < 1 || date.month > 12) return date;
|
|
388
|
+
} else if (map.MMM) {
|
|
389
|
+
date.month = monthsShort.indexOf(match[map.MMM]) + 1;
|
|
390
|
+
} else if (map.MMMM) {
|
|
391
|
+
date.month = months.indexOf(match[map.MMMM]) + 1;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (map.D) {
|
|
395
|
+
date.day = parseInt(match[map.D], 10);
|
|
396
|
+
if (date.year === null || date.month === null || date.day < 1) return date;
|
|
397
|
+
|
|
398
|
+
const maxDay = new Date(date.year as number, date.month as number, 0).getDate();
|
|
399
|
+
if (date.day > maxDay) return date;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (map.H) {
|
|
403
|
+
date.hour = parseInt(match[map.H], 10) % 24;
|
|
404
|
+
} else if (map.h) {
|
|
405
|
+
date.hour = parseInt(match[map.h], 10) % 12;
|
|
406
|
+
|
|
407
|
+
if (
|
|
408
|
+
(map.A && match[map.A] === 'PM') ||
|
|
409
|
+
(map.a && match[map.a] === 'pm') ||
|
|
410
|
+
(map.aa && match[map.aa] === 'p.m.')
|
|
411
|
+
) {
|
|
412
|
+
date.hour += 12;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
date.hour = date.hour % 24;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (map.m) {
|
|
419
|
+
date.minute = parseInt(match[map.m], 10) % 60;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (map.s) {
|
|
423
|
+
date.second = parseInt(match[map.s], 10) % 60;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (map.S) {
|
|
427
|
+
date.millisecond = parseInt(match[map.S], 10) * 10 ** (3 - match[map.S].length);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (map.Z || map.ZZ) {
|
|
431
|
+
tzString = map.Z ? match[map.Z].replace(':', '') : match[map.ZZ];
|
|
432
|
+
date.timezoneOffset = (tzString[0] === '+' ? -1 : 1) * (60 * +tzString.slice(1, 3) + +tzString.slice(3, 5));
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
date.dateHash = pad(date.year as number, 6) + '/' + pad(date.month as number) + '/' + pad(date.day as number);
|
|
437
|
+
date.timeHash =
|
|
438
|
+
pad(date.hour as number) + ':' + pad(date.minute as number) + ':' + pad(date.second as number) + tzString;
|
|
439
|
+
|
|
440
|
+
return date;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Check a date string for validity.
|
|
445
|
+
* @param date
|
|
446
|
+
*/
|
|
447
|
+
export function isValid(date: any): boolean {
|
|
448
|
+
return typeof date === 'number' ? true : !isNaN(Date.parse(date));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* The following method is just a wrapper to help you in cases where you just need current time but with a different year, or month, or second etc.
|
|
453
|
+
* @param modified
|
|
454
|
+
* @param utc
|
|
455
|
+
*/
|
|
456
|
+
export function buildDate(modified: IRawDate, utc: boolean) {
|
|
457
|
+
return adjustDate(new Date(), modified, utc);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Get the day number in week for a given date.
|
|
462
|
+
* @param date
|
|
463
|
+
*/
|
|
464
|
+
export function getDayOfWeek(date: Date): number {
|
|
465
|
+
const dow = new Date(date).getDay();
|
|
466
|
+
return dow === 0 ? 7 : dow;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Get the week number in year for a given date.
|
|
471
|
+
* @param date
|
|
472
|
+
*/
|
|
473
|
+
export function getWeekOfYear(date: Date): number {
|
|
474
|
+
const thursday = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
475
|
+
thursday.setDate(thursday.getDate() - ((thursday.getDay() + 6) % 7) + 3);
|
|
476
|
+
|
|
477
|
+
const firstThursday = new Date(thursday.getFullYear(), 0, 4);
|
|
478
|
+
firstThursday.setDate(firstThursday.getDate() - ((firstThursday.getDay() + 6) % 7) + 3);
|
|
479
|
+
|
|
480
|
+
const ds = thursday.getTimezoneOffset() - firstThursday.getTimezoneOffset();
|
|
481
|
+
thursday.setHours(thursday.getHours() - ds);
|
|
482
|
+
|
|
483
|
+
const weekDiff = (+thursday - +firstThursday) / (MILLISECONDS_IN_DAY * 7);
|
|
484
|
+
return 1 + Math.floor(weekDiff);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Get the day of the year from a given date.
|
|
489
|
+
* @param date
|
|
490
|
+
*/
|
|
491
|
+
export function getDayOfYear(date: Date): number | undefined {
|
|
492
|
+
const dayOfYear = getDateDiff(date, startOfDate(date, 'year'), 'days');
|
|
493
|
+
return dayOfYear ? dayOfYear + 1 : undefined;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Check a date is in a given date/time range.
|
|
498
|
+
* @param date
|
|
499
|
+
* @param from
|
|
500
|
+
* @param to
|
|
501
|
+
* @param opts
|
|
502
|
+
*/
|
|
503
|
+
export function isBetweenDates(
|
|
504
|
+
date: Date,
|
|
505
|
+
from: Date,
|
|
506
|
+
to: Date,
|
|
507
|
+
opts: { onlyDate: boolean; inclusiveFrom: boolean; inclusiveTo: boolean }
|
|
508
|
+
): boolean {
|
|
509
|
+
const date1 = getDateIdentifier(from, opts.onlyDate);
|
|
510
|
+
const date2 = getDateIdentifier(to, opts.onlyDate);
|
|
511
|
+
const current = getDateIdentifier(date, opts.onlyDate);
|
|
512
|
+
|
|
513
|
+
return (
|
|
514
|
+
(current > date1 || (opts.inclusiveFrom && current === date1)) &&
|
|
515
|
+
(current < date2 || (opts.inclusiveTo && current === date2))
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Add a given date/time unit from a given date.
|
|
521
|
+
* @param date
|
|
522
|
+
* @param modified
|
|
523
|
+
*/
|
|
524
|
+
export function addToDate(date: Date, modified: IRawDate): Date {
|
|
525
|
+
return getChange(date, modified, 1);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Subtract a given date/time unit from a given date.
|
|
530
|
+
* @param date
|
|
531
|
+
* @param modified
|
|
532
|
+
*/
|
|
533
|
+
export function subtractFromDate(date: Date, modified: IRawDate): Date {
|
|
534
|
+
return getChange(date, modified, -1);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Beginning of a given date/time unit for a given date.
|
|
539
|
+
* @param date
|
|
540
|
+
* @param unit
|
|
541
|
+
* @param utc
|
|
542
|
+
*/
|
|
543
|
+
export function startOfDate(date: Date, unit: string, utc?: boolean): Date {
|
|
544
|
+
const _date = new Date(date);
|
|
545
|
+
const prefix = `set${utc ? 'UTC' : ''}`;
|
|
546
|
+
|
|
547
|
+
switch (unit) {
|
|
548
|
+
case 'year':
|
|
549
|
+
case 'years':
|
|
550
|
+
(_date as Date & Record<string, any>)[`${prefix}Month`](0);
|
|
551
|
+
// eslint-disable-next-line no-fallthrough
|
|
552
|
+
case 'month':
|
|
553
|
+
case 'months':
|
|
554
|
+
(_date as Date & Record<string, any>)[`${prefix}Date`](1);
|
|
555
|
+
// eslint-disable-next-line no-fallthrough
|
|
556
|
+
case 'day':
|
|
557
|
+
case 'days':
|
|
558
|
+
case 'date':
|
|
559
|
+
(_date as Date & Record<string, any>)[`${prefix}Hours`](0);
|
|
560
|
+
// eslint-disable-next-line no-fallthrough
|
|
561
|
+
case 'hour':
|
|
562
|
+
case 'hours':
|
|
563
|
+
(_date as Date & Record<string, any>)[`${prefix}Minutes`](0);
|
|
564
|
+
// eslint-disable-next-line no-fallthrough
|
|
565
|
+
case 'minute':
|
|
566
|
+
case 'minutes':
|
|
567
|
+
(_date as Date & Record<string, any>)[`${prefix}Seconds`](0);
|
|
568
|
+
// eslint-disable-next-line no-fallthrough
|
|
569
|
+
case 'second':
|
|
570
|
+
case 'seconds':
|
|
571
|
+
(_date as Date & Record<string, any>)[`${prefix}Milliseconds`](0);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
return _date;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* End of a given date/time unit for a given date.
|
|
579
|
+
* @param date
|
|
580
|
+
* @param unit
|
|
581
|
+
* @param utc
|
|
582
|
+
*/
|
|
583
|
+
export function endOfDate(date: Date, unit: string, utc: boolean): Date {
|
|
584
|
+
const _date = new Date(date),
|
|
585
|
+
prefix = `set${utc ? 'UTC' : ''}`;
|
|
586
|
+
|
|
587
|
+
switch (unit) {
|
|
588
|
+
case 'year':
|
|
589
|
+
case 'years':
|
|
590
|
+
(_date as Date & Record<string, any>)[`${prefix}Month`](11);
|
|
591
|
+
// eslint-disable-next-line no-fallthrough
|
|
592
|
+
case 'month':
|
|
593
|
+
case 'months':
|
|
594
|
+
(_date as Date & Record<string, any>)[`${prefix}Date`](daysInMonth(_date));
|
|
595
|
+
// eslint-disable-next-line no-fallthrough
|
|
596
|
+
case 'day':
|
|
597
|
+
case 'days':
|
|
598
|
+
case 'date':
|
|
599
|
+
(_date as Date & Record<string, any>)[`${prefix}Hours`](23);
|
|
600
|
+
// eslint-disable-next-line no-fallthrough
|
|
601
|
+
case 'hour':
|
|
602
|
+
case 'hours':
|
|
603
|
+
(_date as Date & Record<string, any>)[`${prefix}Minutes`](59);
|
|
604
|
+
// eslint-disable-next-line no-fallthrough
|
|
605
|
+
case 'minute':
|
|
606
|
+
case 'minutes':
|
|
607
|
+
(_date as Date & Record<string, any>)[`${prefix}Seconds`](59);
|
|
608
|
+
// eslint-disable-next-line no-fallthrough
|
|
609
|
+
case 'second':
|
|
610
|
+
case 'seconds':
|
|
611
|
+
(_date as Date & Record<string, any>)[`${prefix}Milliseconds`](999);
|
|
612
|
+
}
|
|
613
|
+
return _date;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Get the maximum date from a given date and other dates.
|
|
618
|
+
* @param date
|
|
619
|
+
* @param args
|
|
620
|
+
*/
|
|
621
|
+
export function getMaxDate(date: Date, ...args: Date[]): Date {
|
|
622
|
+
let _date = new Date(date) as unknown as number;
|
|
623
|
+
Array.prototype.slice.call(args, 1).forEach((date) => {
|
|
624
|
+
_date = Math.max(_date, new Date(date) as unknown as number);
|
|
625
|
+
});
|
|
626
|
+
return _date as unknown as Date;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Get the minimum date from a given date and other dates.
|
|
631
|
+
* @param date
|
|
632
|
+
* @param args
|
|
633
|
+
*/
|
|
634
|
+
export function getMinDate(date: Date, ...args: Date[]): Date {
|
|
635
|
+
let _date = new Date(date) as unknown as number;
|
|
636
|
+
Array.prototype.slice.call(args, 1).forEach((date) => {
|
|
637
|
+
_date = Math.min(_date, new Date(date) as unknown as number);
|
|
638
|
+
});
|
|
639
|
+
return _date as unknown as Date;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Get the difference between two dates.
|
|
644
|
+
* @param date
|
|
645
|
+
* @param subtract
|
|
646
|
+
* @param unit
|
|
647
|
+
*/
|
|
648
|
+
export function getDateDiff(date: Date, subtract: Date, unit = 'days'): number {
|
|
649
|
+
const date1 = new Date(date);
|
|
650
|
+
const date2 = new Date(subtract);
|
|
651
|
+
|
|
652
|
+
switch (unit) {
|
|
653
|
+
case 'years':
|
|
654
|
+
case 'year':
|
|
655
|
+
return date1.getFullYear() - date2.getFullYear();
|
|
656
|
+
|
|
657
|
+
case 'months':
|
|
658
|
+
case 'month':
|
|
659
|
+
return (date1.getFullYear() - date2.getFullYear()) * 12 + date1.getMonth() - date2.getMonth();
|
|
660
|
+
|
|
661
|
+
case 'days':
|
|
662
|
+
case 'day':
|
|
663
|
+
case 'date':
|
|
664
|
+
return getDiff(startOfDate(date1, 'day'), startOfDate(date2, 'day'), MILLISECONDS_IN_DAY);
|
|
665
|
+
|
|
666
|
+
case 'hours':
|
|
667
|
+
case 'hour':
|
|
668
|
+
return getDiff(startOfDate(date1, 'hour'), startOfDate(date2, 'hour'), MILLISECONDS_IN_HOUR);
|
|
669
|
+
|
|
670
|
+
case 'minutes':
|
|
671
|
+
case 'minute':
|
|
672
|
+
return getDiff(startOfDate(date1, 'minute'), startOfDate(date2, 'minute'), MILLISECONDS_IN_MINUTE);
|
|
673
|
+
|
|
674
|
+
case 'seconds':
|
|
675
|
+
case 'second':
|
|
676
|
+
return getDiff(startOfDate(date1, 'second'), startOfDate(date2, 'second'), 1000);
|
|
677
|
+
|
|
678
|
+
default:
|
|
679
|
+
return 0;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Get date format
|
|
685
|
+
* @param date
|
|
686
|
+
*/
|
|
687
|
+
export function inferDateFormat(date: Date | any): 'date' | 'number' | 'string' {
|
|
688
|
+
return isDate(date) ? 'date' : typeof date === 'number' ? 'number' : 'string';
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Normalize a date in a given date/time range.
|
|
693
|
+
* @param date
|
|
694
|
+
* @param min
|
|
695
|
+
* @param max
|
|
696
|
+
*/
|
|
697
|
+
export function getDateBetween(date: Date, min: Date, max: Date): Date {
|
|
698
|
+
const t = new Date(date);
|
|
699
|
+
|
|
700
|
+
if (min) {
|
|
701
|
+
const low = new Date(min);
|
|
702
|
+
if (t < low) {
|
|
703
|
+
return low;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
if (max) {
|
|
708
|
+
const high = new Date(max);
|
|
709
|
+
if (t > high) {
|
|
710
|
+
return high;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
return t;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Check of two dates unit are equal.
|
|
719
|
+
* @param date1
|
|
720
|
+
* @param date2
|
|
721
|
+
* @param unit
|
|
722
|
+
*/
|
|
723
|
+
export function isSameDate(date1: Date, date2: Date, unit: string): boolean {
|
|
724
|
+
const _date1 = new Date(date1);
|
|
725
|
+
const _date2 = new Date(date2);
|
|
726
|
+
|
|
727
|
+
if (unit === void 0) {
|
|
728
|
+
return _date1.getTime() === _date2.getTime();
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
switch (unit) {
|
|
732
|
+
case 'second':
|
|
733
|
+
case 'seconds':
|
|
734
|
+
if (_date1.getSeconds() !== _date2.getSeconds()) {
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
// eslint-disable-next-line no-fallthrough
|
|
738
|
+
case 'minute':
|
|
739
|
+
case 'minutes':
|
|
740
|
+
if (_date1.getMinutes() !== _date2.getMinutes()) {
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
// eslint-disable-next-line no-fallthrough
|
|
744
|
+
case 'hour':
|
|
745
|
+
case 'hours':
|
|
746
|
+
if (_date1.getHours() !== _date2.getHours()) {
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
// eslint-disable-next-line no-fallthrough
|
|
750
|
+
case 'day':
|
|
751
|
+
case 'days':
|
|
752
|
+
case 'date':
|
|
753
|
+
if (_date1.getDate() !== _date2.getDate()) {
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
// eslint-disable-next-line no-fallthrough
|
|
757
|
+
case 'month':
|
|
758
|
+
case 'months':
|
|
759
|
+
if (_date1.getMonth() !== _date2.getMonth()) {
|
|
760
|
+
return false;
|
|
761
|
+
}
|
|
762
|
+
// eslint-disable-next-line no-fallthrough
|
|
763
|
+
case 'year':
|
|
764
|
+
case 'years':
|
|
765
|
+
if (_date1.getFullYear() !== _date2.getFullYear()) {
|
|
766
|
+
return false;
|
|
767
|
+
}
|
|
768
|
+
break;
|
|
769
|
+
default:
|
|
770
|
+
throw new Error(`date isSameDate unknown unit ${unit}`);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
return true;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Get the number of days in a month.
|
|
778
|
+
* @param date
|
|
779
|
+
*/
|
|
780
|
+
export function daysInMonth(date: Date): number {
|
|
781
|
+
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Cloning date object.
|
|
786
|
+
* @param date
|
|
787
|
+
*/
|
|
788
|
+
export function clone(date: Date): Date {
|
|
789
|
+
return isDate(date) ? new Date(date.getTime()) : date;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
function getRegexData(mask: string, dateLocale: TDateLocale): { map: Record<string, any>; regex: RegExp } {
|
|
793
|
+
const days = '(' + dateLocale.days.join('|') + ')';
|
|
794
|
+
const key = mask + days;
|
|
795
|
+
|
|
796
|
+
if (regexStore[key]) return regexStore[key];
|
|
797
|
+
|
|
798
|
+
const daysShort = '(' + dateLocale.daysShort.join('|') + ')';
|
|
799
|
+
const months = '(' + dateLocale.months.join('|') + ')';
|
|
800
|
+
const monthsShort = '(' + dateLocale.monthsShort.join('|') + ')';
|
|
801
|
+
|
|
802
|
+
const map: Record<string, any> = {};
|
|
803
|
+
let index = 0;
|
|
804
|
+
|
|
805
|
+
const regexText = mask.replace(reverseToken, (match) => {
|
|
806
|
+
index++;
|
|
807
|
+
switch (match) {
|
|
808
|
+
case 'YY':
|
|
809
|
+
map.YY = index;
|
|
810
|
+
return '(-?\\d{1,2})';
|
|
811
|
+
case 'YYYY':
|
|
812
|
+
map.YYYY = index;
|
|
813
|
+
return '(-?\\d{1,4})';
|
|
814
|
+
case 'M':
|
|
815
|
+
map.M = index;
|
|
816
|
+
return '(\\d{1,2})';
|
|
817
|
+
case 'MM':
|
|
818
|
+
map.M = index; // bumping to M
|
|
819
|
+
return '(\\d{2})';
|
|
820
|
+
case 'MMM':
|
|
821
|
+
map.MMM = index;
|
|
822
|
+
return monthsShort;
|
|
823
|
+
case 'MMMM':
|
|
824
|
+
map.MMMM = index;
|
|
825
|
+
return months;
|
|
826
|
+
case 'D':
|
|
827
|
+
map.D = index;
|
|
828
|
+
return '(\\d{1,2})';
|
|
829
|
+
case 'Do':
|
|
830
|
+
map.D = index++; // bumping to D
|
|
831
|
+
return '(\\d{1,2}(st|nd|rd|th))';
|
|
832
|
+
case 'DD':
|
|
833
|
+
map.D = index; // bumping to D
|
|
834
|
+
return '(\\d{2})';
|
|
835
|
+
case 'H':
|
|
836
|
+
map.H = index;
|
|
837
|
+
return '(\\d{1,2})';
|
|
838
|
+
case 'HH':
|
|
839
|
+
map.H = index; // bumping to H
|
|
840
|
+
return '(\\d{2})';
|
|
841
|
+
case 'h':
|
|
842
|
+
map.h = index;
|
|
843
|
+
return '(\\d{1,2})';
|
|
844
|
+
case 'hh':
|
|
845
|
+
map.h = index; // bumping to h
|
|
846
|
+
return '(\\d{2})';
|
|
847
|
+
case 'm':
|
|
848
|
+
map.m = index;
|
|
849
|
+
return '(\\d{1,2})';
|
|
850
|
+
case 'mm':
|
|
851
|
+
map.m = index; // bumping to m
|
|
852
|
+
return '(\\d{2})';
|
|
853
|
+
case 's':
|
|
854
|
+
map.s = index;
|
|
855
|
+
return '(\\d{1,2})';
|
|
856
|
+
case 'ss':
|
|
857
|
+
map.s = index; // bumping to s
|
|
858
|
+
return '(\\d{2})';
|
|
859
|
+
case 'S':
|
|
860
|
+
map.S = index;
|
|
861
|
+
return '(\\d{1})';
|
|
862
|
+
case 'SS':
|
|
863
|
+
map.S = index; // bump to S
|
|
864
|
+
return '(\\d{2})';
|
|
865
|
+
case 'SSS':
|
|
866
|
+
map.S = index; // bump to S
|
|
867
|
+
return '(\\d{3})';
|
|
868
|
+
case 'A':
|
|
869
|
+
map.A = index;
|
|
870
|
+
return '(AM|PM)';
|
|
871
|
+
case 'a':
|
|
872
|
+
map.a = index;
|
|
873
|
+
return '(am|pm)';
|
|
874
|
+
case 'aa':
|
|
875
|
+
map.aa = index;
|
|
876
|
+
return '(a\\.m\\.|p\\.m\\.)';
|
|
877
|
+
|
|
878
|
+
case 'ddd':
|
|
879
|
+
return daysShort;
|
|
880
|
+
case 'dddd':
|
|
881
|
+
return days;
|
|
882
|
+
case 'Q':
|
|
883
|
+
case 'd':
|
|
884
|
+
case 'E':
|
|
885
|
+
return '(\\d{1})';
|
|
886
|
+
case 'Qo':
|
|
887
|
+
return '(1st|2nd|3rd|4th)';
|
|
888
|
+
case 'DDD':
|
|
889
|
+
case 'DDDD':
|
|
890
|
+
return '(\\d{1,3})';
|
|
891
|
+
case 'w':
|
|
892
|
+
return '(\\d{1,2})';
|
|
893
|
+
case 'ww':
|
|
894
|
+
return '(\\d{2})';
|
|
895
|
+
|
|
896
|
+
case 'Z': // to split: (?:(Z)()()|([+-])?(\\d{2}):?(\\d{2}))
|
|
897
|
+
map.Z = index;
|
|
898
|
+
return '(Z|[+-]\\d{2}:\\d{2})';
|
|
899
|
+
case 'ZZ':
|
|
900
|
+
map.ZZ = index;
|
|
901
|
+
return '(Z|[+-]\\d{2}\\d{2})';
|
|
902
|
+
|
|
903
|
+
case 'X':
|
|
904
|
+
map.X = index;
|
|
905
|
+
return '(-?\\d+)';
|
|
906
|
+
case 'x':
|
|
907
|
+
map.x = index;
|
|
908
|
+
return '(-?\\d{4,})';
|
|
909
|
+
|
|
910
|
+
default:
|
|
911
|
+
index--;
|
|
912
|
+
if (match[0] === '[') {
|
|
913
|
+
match = match.substring(1, match.length - 1);
|
|
914
|
+
}
|
|
915
|
+
return match.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
const result = { map, regex: new RegExp('^' + regexText) };
|
|
920
|
+
regexStore[key] = result;
|
|
921
|
+
|
|
922
|
+
return result;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
function getDateLocale(paramDateLocale: TDateLocale, locale: ILocale): TDateLocale {
|
|
926
|
+
return paramDateLocale ? paramDateLocale : locale ? locale.date : defaultLang.date;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
function formatTimezone(offset: number, delimiter: string = ''): string {
|
|
930
|
+
const sign = offset > 0 ? '-' : '+';
|
|
931
|
+
const absOffset = Math.abs(offset);
|
|
932
|
+
const hours = Math.floor(absOffset / 60);
|
|
933
|
+
const minutes = absOffset % 60;
|
|
934
|
+
|
|
935
|
+
return sign + pad(hours) + delimiter + pad(minutes);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
function applyYearMonthDayChange(date: Date, modified: IRawDate, sign: number): Date {
|
|
939
|
+
let year = date.getFullYear();
|
|
940
|
+
let month = date.getMonth();
|
|
941
|
+
const day = date.getMonth();
|
|
942
|
+
|
|
943
|
+
if (modified.year) {
|
|
944
|
+
year += sign * modified.year;
|
|
945
|
+
delete modified.year;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
if (modified.month) {
|
|
949
|
+
month += sign * modified.month;
|
|
950
|
+
delete modified.month;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
date.setDate(1);
|
|
954
|
+
date.setMonth(2);
|
|
955
|
+
date.setFullYear(year);
|
|
956
|
+
date.setMonth(month);
|
|
957
|
+
date.setDate(Math.min(day, daysInMonth(date)));
|
|
958
|
+
|
|
959
|
+
if (modified.date) {
|
|
960
|
+
date.setDate(date.getDate() + sign * modified.date);
|
|
961
|
+
delete modified.date;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
return date;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
function applyYearMonthDay(date: Date, modified: IRawDate, middle: string): Date {
|
|
968
|
+
const year = modified.year ? modified.year : (date as any)[`get${middle}FullYear`]();
|
|
969
|
+
const month = modified.month ? modified.month - 1 : (date as any)[`get${middle}Month`]();
|
|
970
|
+
const maxDay = new Date(year, month + 1, 0).getDate();
|
|
971
|
+
const day = Math.min(maxDay, modified.date ? modified.date : (date as any)[`get${middle}Date`]());
|
|
972
|
+
|
|
973
|
+
(date as Date & Record<string, any>)[`set${middle}Date`](1);
|
|
974
|
+
(date as Date & Record<string, any>)[`set${middle}Month`](2);
|
|
975
|
+
(date as Date & Record<string, any>)[`set${middle}FullYear`](year);
|
|
976
|
+
(date as Date & Record<string, any>)[`set${middle}Month`](month);
|
|
977
|
+
(date as Date & Record<string, any>)[`set${middle}Date`](day);
|
|
978
|
+
|
|
979
|
+
delete modified.year;
|
|
980
|
+
delete modified.month;
|
|
981
|
+
delete modified.date;
|
|
982
|
+
|
|
983
|
+
return date;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
function getChange(date: Date, rawModified: IRawDate & Record<string, any>, sign: number): Date {
|
|
987
|
+
const modified = normalizeModified(rawModified);
|
|
988
|
+
const _date = new Date(date);
|
|
989
|
+
const changedDate =
|
|
990
|
+
modified.year || modified.month || modified.date ? applyYearMonthDayChange(date, modified, sign) : _date;
|
|
991
|
+
|
|
992
|
+
for (const key in modified) {
|
|
993
|
+
const op = key.charAt(0).toUpperCase() + key.slice(1);
|
|
994
|
+
(changedDate as Date & Record<string, any>)[`set${op}`]((changedDate as Date & Record<string, any>)[`get${op}`])() +
|
|
995
|
+
sign * modified[key];
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
return changedDate;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
function normalizeModified(modified: IRawDate & Record<string, any>) {
|
|
1002
|
+
const acc = { ...modified };
|
|
1003
|
+
|
|
1004
|
+
if (modified.years) {
|
|
1005
|
+
acc.year = modified.years;
|
|
1006
|
+
delete acc.years;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
if (modified.months) {
|
|
1010
|
+
acc.month = modified.months;
|
|
1011
|
+
delete acc.months;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
if (modified.days) {
|
|
1015
|
+
acc.date = modified.days;
|
|
1016
|
+
delete acc.days;
|
|
1017
|
+
}
|
|
1018
|
+
if (modified.day) {
|
|
1019
|
+
acc.date = modified.day;
|
|
1020
|
+
delete acc.day;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
if (modified.hour) {
|
|
1024
|
+
acc.hours = modified.hour;
|
|
1025
|
+
delete acc.hour;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
if (modified.minute) {
|
|
1029
|
+
acc.minutes = modified.minute;
|
|
1030
|
+
delete acc.minute;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
if (modified.second) {
|
|
1034
|
+
acc.seconds = modified.second;
|
|
1035
|
+
delete acc.second;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
if (modified.millisecond) {
|
|
1039
|
+
acc.milliseconds = modified.millisecond;
|
|
1040
|
+
delete acc.millisecond;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
return acc;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
function getDayIdentifier(date: Date): number {
|
|
1047
|
+
return date.getFullYear() * 10000 + date.getMonth() * 100 + date.getDate();
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
function getDateIdentifier(date: Date, onlyDate?: boolean): number {
|
|
1051
|
+
const _date = new Date(date);
|
|
1052
|
+
return onlyDate ? getDayIdentifier(_date) : _date.getTime();
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
function getDiff(date1: Date, date2: Date, interval: number): number {
|
|
1056
|
+
return (
|
|
1057
|
+
(date1.getTime() -
|
|
1058
|
+
date1.getTimezoneOffset() * MILLISECONDS_IN_MINUTE -
|
|
1059
|
+
(date2.getTime() - date2.getTimezoneOffset() * MILLISECONDS_IN_MINUTE)) /
|
|
1060
|
+
interval
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
function getOrdinal(n: number) {
|
|
1065
|
+
if (n >= 11 && n <= 13) {
|
|
1066
|
+
return `${n}th`;
|
|
1067
|
+
}
|
|
1068
|
+
switch (n % 10) {
|
|
1069
|
+
case 1:
|
|
1070
|
+
return `${n}st`;
|
|
1071
|
+
case 2:
|
|
1072
|
+
return `${n}nd`;
|
|
1073
|
+
case 3:
|
|
1074
|
+
return `${n}rd`;
|
|
1075
|
+
}
|
|
1076
|
+
return `${n}th`;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
export default {
|
|
1080
|
+
formatDate,
|
|
1081
|
+
clone,
|
|
1082
|
+
isValid,
|
|
1083
|
+
buildDate,
|
|
1084
|
+
getDayOfWeek,
|
|
1085
|
+
getWeekOfYear,
|
|
1086
|
+
isBetweenDates,
|
|
1087
|
+
addToDate,
|
|
1088
|
+
subtractFromDate,
|
|
1089
|
+
adjustDate,
|
|
1090
|
+
startOfDate,
|
|
1091
|
+
endOfDate,
|
|
1092
|
+
getMaxDate,
|
|
1093
|
+
getMinDate,
|
|
1094
|
+
getDateDiff,
|
|
1095
|
+
getDayOfYear,
|
|
1096
|
+
inferDateFormat,
|
|
1097
|
+
getDateBetween,
|
|
1098
|
+
isSameDate,
|
|
1099
|
+
daysInMonth
|
|
1100
|
+
};
|