@bbn/bbn 2.0.94 → 2.0.96

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/date.js DELETED
@@ -1,1506 +0,0 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _bbnDateDuration_instances, _bbnDateDuration_durationMs, _bbnDateDuration_unit, _bbnDateDuration_getUnitRowByName, _bbnDateDuration_getUnitValue, _bbnDateTool_value, _bbnDateTool_isDuration;
13
- import _ from './_.js';
14
- import each from './fn/loop/each.js';
15
- import substr from './fn/string/substr.js';
16
- import isNumber from './fn/type/isNumber.js';
17
- import isDate from './fn/type/isDate.js';
18
- import isPrimitive from './fn/type/isPrimitive.js';
19
- import extend from './fn/object/extend.js';
20
- import getRow from './fn/object/getRow.js';
21
- const patterns = [
22
- // MariaDB DATETIME "YYYY-MM-DD HH:MM:SS"
23
- {
24
- name: 'mariadb-datetime',
25
- re: /^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2}):(\d{2})$/,
26
- map: m => ({
27
- year: +m[1],
28
- month: +m[2],
29
- day: +m[3],
30
- hour: +m[4],
31
- minute: +m[5],
32
- second: +m[6],
33
- })
34
- },
35
- // MariaDB DATETIME without seconds "YYYY-MM-DD HH:MM"
36
- {
37
- name: 'mariadb-datetime-no-sec',
38
- re: /^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2})$/,
39
- map: m => ({
40
- year: +m[1],
41
- month: +m[2],
42
- day: +m[3],
43
- hour: +m[4],
44
- minute: +m[5],
45
- second: 0,
46
- })
47
- },
48
- // MariaDB DATE "YYYY-MM-DD"
49
- {
50
- name: 'mariadb-date',
51
- re: /^(\d{4})-(\d{2})-(\d{2})$/,
52
- map: m => ({
53
- year: +m[1],
54
- month: +m[2],
55
- day: +m[3],
56
- hour: 0,
57
- minute: 0,
58
- second: 0,
59
- })
60
- },
61
- // ISO / JS-style "YYYY-MM-DDTHH:MM[:SS][.sss][Z or ±HH:MM]"
62
- {
63
- name: 'iso-datetime',
64
- re: /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2}))?(?:\.\d+)?(?:Z|[+\-]\d{2}:?\d{2})?$/,
65
- map: m => ({
66
- year: +m[1],
67
- month: +m[2],
68
- day: +m[3],
69
- hour: +m[4],
70
- minute: +m[5],
71
- second: m[6] !== undefined ? +m[6] : 0,
72
- })
73
- },
74
- // Simple slash date "YYYY/MM/DD"
75
- {
76
- name: 'slash-date',
77
- re: /^(\d{2})\/(\d{2})\/(\d{4})$/,
78
- map: m => ({
79
- year: +m[3],
80
- month: +m[2],
81
- day: +m[1],
82
- hour: 0,
83
- minute: 0,
84
- second: 0,
85
- })
86
- },
87
- // Slash datetime "YYYY/MM/DD HH:MM:SS"
88
- {
89
- name: 'slash-datetime',
90
- re: /^(\d{2})\/(\d{2})\/(\d{4})[ T](\d{2}):(\d{2}):(\d{2})$/,
91
- map: m => ({
92
- year: +m[3],
93
- month: +m[2],
94
- day: +m[1],
95
- hour: +m[4],
96
- minute: +m[5],
97
- second: +m[6],
98
- })
99
- },
100
- ];
101
- const units = [
102
- ['y', "year", 365 * 24 * 60 * 60 * 1000],
103
- ['m', "month", 30 * 24 * 60 * 60 * 1000],
104
- ['w', "week", 7 * 24 * 60 * 60 * 1000],
105
- ['d', "day", 24 * 60 * 60 * 1000],
106
- ['h', "hour", 60 * 60 * 1000],
107
- ['i', "minute", 60 * 1000],
108
- ['s', "second", 1000]
109
- ];
110
- const unitsMap = {
111
- 'y': 'Year',
112
- 'm': 'Month',
113
- 'd': 'Date',
114
- 'w': 'Week',
115
- 'h': 'Hours',
116
- 'i': 'Minutes',
117
- 's': 'Seconds'
118
- };
119
- const formatsMap = {
120
- 'y': 'YYYY',
121
- 'm': 'MM',
122
- 'd': 'DD',
123
- 'e': 'EE',
124
- 'w': 'WW',
125
- 'h': 'HH',
126
- 'i': 'II',
127
- 's': 'SS'
128
- };
129
- const unitsCorrespondence = {
130
- 'years': 'y',
131
- 'year': 'y',
132
- 'YEARS': 'y',
133
- 'YEAR': 'y',
134
- 'Years': 'y',
135
- 'Year': 'y',
136
- 'YYYY': 'y',
137
- 'YY': 'y',
138
- 'yyyy': 'y',
139
- 'yy': 'y',
140
- 'months': 'm',
141
- 'month': 'm',
142
- 'Months': 'm',
143
- 'Month': 'm',
144
- 'MONTHS': 'm',
145
- 'MONTH': 'm',
146
- 'MMMM': 'm',
147
- 'MMM': 'm',
148
- 'MM': 'm',
149
- 'weekday': 'e',
150
- 'WEEKDAY': 'e',
151
- 'ee': 'e',
152
- 'EE': 'e',
153
- 'ddd': 'e',
154
- 'days': 'd',
155
- 'day': 'd',
156
- 'Days': 'd',
157
- 'Day': 'd',
158
- 'DAYS': 'd',
159
- 'DAY': 'd',
160
- 'DD': 'd',
161
- 'dd': 'd',
162
- 'hours': 'h',
163
- 'hour': 'h',
164
- 'Hours': 'h',
165
- 'Hour': 'h',
166
- 'HOURS': 'h',
167
- 'HOUR': 'h',
168
- 'HH': 'h',
169
- 'hr': 'h',
170
- 'hh': 'h',
171
- 'minutes': 'i',
172
- 'minute': 'i',
173
- 'Minutes': 'i',
174
- 'Minute': 'i',
175
- 'MINUTES': 'i',
176
- 'MINUTE': 'i',
177
- 'II': 'i',
178
- 'ii': 'i',
179
- 'mn': 'i',
180
- 'mm': 'i',
181
- 'min': 'i',
182
- 'SS': 's',
183
- 'ss': 's',
184
- 'seconds': 's',
185
- 'second': 's',
186
- 'Seconds': 's',
187
- 'Second': 's',
188
- 'SECONDS': 's',
189
- 'SECOND': 's',
190
- 'sec': 's',
191
- 'WW': 'w',
192
- 'Y': 'y',
193
- 'y': 'y',
194
- 'M': 'm',
195
- 'm': 'm',
196
- 'e': 'e',
197
- 'E': 'e',
198
- 'D': 'd',
199
- 'd': 'd',
200
- 'H': 'h',
201
- 'h': 'h',
202
- 'n': 'i',
203
- 'i': 'i',
204
- 's': 's',
205
- 'S': 's',
206
- 'W': 'w',
207
- 'w': 'w'
208
- };
209
- const buildLocaleFromIntl = () => {
210
- const langs = [bbn.env.lang, ...navigator.languages];
211
- const fmtMonthLong = new Intl.DateTimeFormat(langs, { month: 'long' });
212
- const fmtMonthShort = new Intl.DateTimeFormat(langs, { month: 'short' });
213
- const fmtWeekLong = new Intl.DateTimeFormat(langs, { weekday: 'long' });
214
- const fmtWeekShort = new Intl.DateTimeFormat(langs, { weekday: 'short' });
215
- // Create 12 dates for months (2020 chosen arbitrarily)
216
- const monthsLong = [];
217
- const monthsShort = [];
218
- for (let m = 0; m < 12; m++) {
219
- const d = new Date(2020, m, 1);
220
- monthsLong.push(fmtMonthLong.format(d));
221
- monthsShort.push(fmtMonthShort.format(d));
222
- }
223
- // Create 7 dates for weekdays (starting from Sunday 2020-02-02 which *is* Sunday)
224
- // 2020-02-02 is Sunday → guarantees stable weekday list
225
- const baseSunday = new Date(2020, 1, 2); // YYYY, MM (0-based), DD
226
- const weekdaysLong = [];
227
- const weekdaysShort = [];
228
- for (let i = 0; i < 7; i++) {
229
- const d = new Date(baseSunday.getTime() + i * 86400000);
230
- weekdaysLong.push(fmtWeekLong.format(d));
231
- weekdaysShort.push(fmtWeekShort.format(d));
232
- }
233
- return {
234
- monthsLong,
235
- monthsShort,
236
- weekdaysLong,
237
- weekdaysShort,
238
- };
239
- };
240
- const locales = {};
241
- class bbnDateDuration {
242
- constructor(len, unit, fromMs = false) {
243
- _bbnDateDuration_instances.add(this);
244
- _bbnDateDuration_durationMs.set(this, 0);
245
- _bbnDateDuration_unit.set(this, '');
246
- const realUnit = unitsCorrespondence[unit] || unit;
247
- if (!realUnit) {
248
- throw new Error('Invalid unit for duration: ' + unit);
249
- }
250
- __classPrivateFieldSet(this, _bbnDateDuration_unit, realUnit, "f");
251
- const row = getRow(units, d => d[0] === realUnit);
252
- if (!row) {
253
- throw new Error('Invalid unit for duration: ' + realUnit);
254
- }
255
- const msPerUnit = row[2];
256
- __classPrivateFieldSet(this, _bbnDateDuration_durationMs, fromMs ? len : len * msPerUnit, "f");
257
- }
258
- // -----------------------
259
- // Public getters
260
- // -----------------------
261
- years(remaining = false) { return __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitValue).call(this, 'year', remaining); }
262
- months(remaining = false) { return __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitValue).call(this, 'month', remaining); }
263
- weeks(remaining = false) { return __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitValue).call(this, 'week', remaining); }
264
- days(remaining = false) { return __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitValue).call(this, 'day', remaining); }
265
- hours(remaining = false) { return __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitValue).call(this, 'hour', remaining); }
266
- minutes(remaining = false) { return __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitValue).call(this, 'minute', remaining); }
267
- seconds(remaining = false) { return __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitValue).call(this, 'second', remaining); }
268
- // -----------------------
269
- // Day.js style
270
- // "asX" conversions
271
- // -----------------------
272
- toJSON() {
273
- return {
274
- years: this.years(true),
275
- months: this.months(true),
276
- days: this.days(true),
277
- hours: this.hours(true),
278
- minutes: this.minutes(true),
279
- seconds: this.seconds(true),
280
- milliseconds: this.toMilliseconds()
281
- };
282
- }
283
- /**
284
- * Returns the full duration expressed as X (float), like Day.js.
285
- */
286
- asYears() {
287
- const [, , ms] = __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitRowByName).call(this, 'year');
288
- return __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") / ms;
289
- }
290
- asMonths() {
291
- const [, , ms] = __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitRowByName).call(this, 'month');
292
- return __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") / ms;
293
- }
294
- asWeeks() {
295
- const [, , ms] = __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitRowByName).call(this, 'week');
296
- return __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") / ms;
297
- }
298
- asDays() {
299
- const [, , ms] = __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitRowByName).call(this, 'day');
300
- return __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") / ms;
301
- }
302
- asHours() {
303
- const [, , ms] = __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitRowByName).call(this, 'hour');
304
- return __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") / ms;
305
- }
306
- asMinutes() {
307
- const [, , ms] = __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitRowByName).call(this, 'minute');
308
- return __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") / ms;
309
- }
310
- asSeconds() {
311
- const [, , ms] = __classPrivateFieldGet(this, _bbnDateDuration_instances, "m", _bbnDateDuration_getUnitRowByName).call(this, 'second');
312
- return __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") / ms;
313
- }
314
- /**
315
- * Add any unit (or instance default).
316
- */
317
- add(value, unit) {
318
- const targetUnit = unit
319
- ? (unitsCorrespondence[unit] || unit)
320
- : __classPrivateFieldGet(this, _bbnDateDuration_unit, "f");
321
- const row = getRow(units, d => d[0] === targetUnit);
322
- if (!row) {
323
- throw new Error('Invalid unit for duration: ' + (unit !== null && unit !== void 0 ? unit : targetUnit));
324
- }
325
- return new bbnDateDuration(__classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") + value * row[2], __classPrivateFieldGet(this, _bbnDateDuration_unit, "f"), true);
326
- }
327
- subtract(value, unit) {
328
- return this.add(-value, unit);
329
- }
330
- toMilliseconds() {
331
- return __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f");
332
- }
333
- }
334
- _bbnDateDuration_durationMs = new WeakMap(), _bbnDateDuration_unit = new WeakMap(), _bbnDateDuration_instances = new WeakSet(), _bbnDateDuration_getUnitRowByName = function _bbnDateDuration_getUnitRowByName(name) {
335
- const row = getRow(units, d => d[1] === name);
336
- if (!row) {
337
- throw new Error('Unit name not found: ' + name);
338
- }
339
- return row;
340
- }, _bbnDateDuration_getUnitValue = function _bbnDateDuration_getUnitValue(name, remaining) {
341
- const index = units.findIndex(([, n]) => n === name);
342
- if (index === -1) {
343
- throw new Error('Unit not found: ' + name);
344
- }
345
- const unitMs = units[index][2];
346
- // Total units
347
- if (!remaining) {
348
- return Math.floor(__classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f") / unitMs);
349
- }
350
- // Remaining units
351
- let remainingMs = __classPrivateFieldGet(this, _bbnDateDuration_durationMs, "f");
352
- for (let i = 0; i < index; i++) {
353
- const [, , msHigher] = units[i];
354
- const amount = Math.floor(remainingMs / msHigher);
355
- remainingMs -= amount * msHigher;
356
- }
357
- return Math.floor(remainingMs / unitMs);
358
- };
359
- class bbnDateTool {
360
- /**
361
- * Parses a date string strictly according to a format.
362
- *
363
- * Supported tokens:
364
- * Years: YYYY, YY, Y
365
- * Months: MMMM, MMM, MM, M, m
366
- * Days: DD, D, d
367
- * Weekday: dddd, ddd, EE (validation only)
368
- * Hours: HH, H, h
369
- * Minutes: II, I, i
370
- * Seconds: SS, S, s
371
- * Milli: ms
372
- * Weeks: WWWW, WWW, WW, W (parsed but not used to build the Date)
373
- *
374
- * @throws Error if parsing fails or the date is invalid.
375
- */
376
- static parse(input, format, locale) {
377
- var _a, _b, _c, _d;
378
- if (!('monthsLong' in locales)) {
379
- extend(locales, buildLocaleFromIntl());
380
- }
381
- const loc = {
382
- monthsLong: (_a = locale === null || locale === void 0 ? void 0 : locale.monthsLong) !== null && _a !== void 0 ? _a : locales.monthsLong,
383
- monthsShort: (_b = locale === null || locale === void 0 ? void 0 : locale.monthsShort) !== null && _b !== void 0 ? _b : locales.monthsShort,
384
- weekdaysLong: (_c = locale === null || locale === void 0 ? void 0 : locale.weekdaysLong) !== null && _c !== void 0 ? _c : locales.weekdaysLong,
385
- weekdaysShort: (_d = locale === null || locale === void 0 ? void 0 : locale.weekdaysShort) !== null && _d !== void 0 ? _d : locales.weekdaysShort
386
- };
387
- const ctx = {
388
- year: 1970,
389
- month: 1,
390
- day: 1,
391
- hour: 0,
392
- minute: 0,
393
- second: 0,
394
- ms: 0
395
- };
396
- const escapeRegex = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
397
- const tokenSpecs = [
398
- // Years
399
- {
400
- token: 'YYYY',
401
- regex: '\\d{4}',
402
- apply: v => { ctx.year = parseInt(v, 10); }
403
- },
404
- {
405
- token: 'YY',
406
- regex: '\\d{2}',
407
- apply: v => {
408
- const n = parseInt(v, 10);
409
- ctx.year = n >= 70 ? 1900 + n : 2000 + n;
410
- }
411
- },
412
- {
413
- token: 'Y',
414
- regex: '[+-]?\\d{1,6}',
415
- apply: v => { ctx.year = parseInt(v, 10); }
416
- },
417
- // Months
418
- {
419
- token: 'MMMM',
420
- regex: '[^\\d\\s]+',
421
- apply: v => {
422
- const idx = loc.monthsLong
423
- .findIndex(m => m.toLowerCase() === v.toLowerCase());
424
- if (idx === -1) {
425
- throw new Error('Invalid month name: ' + v);
426
- }
427
- ctx.month = idx + 1;
428
- }
429
- },
430
- {
431
- token: 'MMM',
432
- regex: '[^\\d\\s]+',
433
- apply: v => {
434
- const idx = loc.monthsShort
435
- .findIndex(m => m.toLowerCase() === v.toLowerCase());
436
- if (idx === -1) {
437
- throw new Error('Invalid short month name: ' + v);
438
- }
439
- ctx.month = idx + 1;
440
- }
441
- },
442
- {
443
- token: 'MM',
444
- regex: '\\d{2}',
445
- apply: v => {
446
- const n = parseInt(v, 10);
447
- if (n < 1 || n > 12) {
448
- throw new Error('Invalid month: ' + n);
449
- }
450
- ctx.month = n;
451
- }
452
- },
453
- {
454
- token: 'mm',
455
- regex: '\\d{2}',
456
- apply: v => {
457
- const n = parseInt(v, 10);
458
- if (n < 0 || n > 59) {
459
- throw new Error('Invalid minute: ' + n);
460
- }
461
- ctx.month = n;
462
- }
463
- },
464
- {
465
- token: 'M',
466
- regex: '\\d{1,2}',
467
- apply: v => {
468
- const n = parseInt(v, 10);
469
- if (n < 1 || n > 12) {
470
- throw new Error('Invalid month: ' + n);
471
- }
472
- ctx.month = n;
473
- }
474
- },
475
- {
476
- token: 'm', // PHP-like month
477
- regex: '\\d{2}',
478
- apply: v => {
479
- const n = parseInt(v, 10);
480
- if (n < 1 || n > 12) {
481
- throw new Error('Invalid month: ' + n);
482
- }
483
- ctx.month = n;
484
- }
485
- },
486
- // Day of month
487
- {
488
- token: 'DD',
489
- regex: '\\d{2}',
490
- apply: v => {
491
- const n = parseInt(v, 10);
492
- if (n < 1 || n > 31) {
493
- throw new Error('Invalid day of month: ' + n);
494
- }
495
- ctx.day = n;
496
- }
497
- },
498
- {
499
- token: 'D',
500
- regex: '\\d{1,2}',
501
- apply: v => {
502
- const n = parseInt(v, 10);
503
- if (n < 1 || n > 31) {
504
- throw new Error('Invalid day of month: ' + n);
505
- }
506
- ctx.day = n;
507
- }
508
- },
509
- {
510
- token: 'd', // PHP-like day-of-month
511
- regex: '\\d{2}',
512
- apply: v => {
513
- const n = parseInt(v, 10);
514
- if (n < 1 || n > 31) {
515
- throw new Error('Invalid day of month: ' + n);
516
- }
517
- ctx.day = n;
518
- }
519
- },
520
- // Weekday (only validated)
521
- {
522
- token: 'dddd',
523
- regex: '[^\\d\\s]+',
524
- apply: v => {
525
- const idx = loc.weekdaysLong
526
- .findIndex(w => w.toLowerCase() === v.toLowerCase());
527
- if (idx === -1) {
528
- throw new Error('Invalid weekday name: ' + v);
529
- }
530
- ctx.weekday = idx; // 0-6, Sunday-based
531
- }
532
- },
533
- {
534
- token: 'ddd',
535
- regex: '[^\\d\\s]+',
536
- apply: v => {
537
- const idx = loc.weekdaysShort
538
- .findIndex(w => w.toLowerCase() === v.toLowerCase());
539
- if (idx === -1) {
540
- throw new Error('Invalid short weekday name: ' + v);
541
- }
542
- ctx.weekday = idx; // 0-6
543
- }
544
- },
545
- {
546
- token: 'EE',
547
- regex: '\\d{1}',
548
- apply: v => {
549
- const n = parseInt(v, 10);
550
- if (n < 0 || n > 7) {
551
- throw new Error('Invalid weekday number: ' + n);
552
- }
553
- ctx.weekday = n;
554
- }
555
- },
556
- // Hours
557
- {
558
- token: 'HH',
559
- regex: '\\d{2}',
560
- apply: v => {
561
- const n = parseInt(v, 10);
562
- if (n < 0 || n > 23) {
563
- throw new Error('Invalid hour: ' + n);
564
- }
565
- ctx.hour = n;
566
- }
567
- },
568
- {
569
- token: 'H',
570
- regex: '\\d{1,2}',
571
- apply: v => {
572
- const n = parseInt(v, 10);
573
- if (n < 0 || n > 23) {
574
- throw new Error('Invalid hour: ' + n);
575
- }
576
- ctx.hour = n;
577
- }
578
- },
579
- {
580
- token: 'h', // PHP-like 24h alias here
581
- regex: '\\d{2}',
582
- apply: v => {
583
- const n = parseInt(v, 10);
584
- if (n < 0 || n > 23) {
585
- throw new Error('Invalid hour: ' + n);
586
- }
587
- ctx.hour = n;
588
- }
589
- },
590
- // Minutes
591
- {
592
- token: 'II',
593
- regex: '\\d{2}',
594
- apply: v => {
595
- const n = parseInt(v, 10);
596
- if (n < 0 || n > 59) {
597
- throw new Error('Invalid minute: ' + n);
598
- }
599
- ctx.minute = n;
600
- }
601
- },
602
- {
603
- token: 'I',
604
- regex: '\\d{1,2}',
605
- apply: v => {
606
- const n = parseInt(v, 10);
607
- if (n < 0 || n > 59) {
608
- throw new Error('Invalid minute: ' + n);
609
- }
610
- ctx.minute = n;
611
- }
612
- },
613
- {
614
- token: 'i', // PHP-like minutes
615
- regex: '\\d{2}',
616
- apply: v => {
617
- const n = parseInt(v, 10);
618
- if (n < 0 || n > 59) {
619
- throw new Error('Invalid minute: ' + n);
620
- }
621
- ctx.minute = n;
622
- }
623
- },
624
- // Seconds
625
- {
626
- token: 'SS',
627
- regex: '\\d{2}',
628
- apply: v => {
629
- const n = parseInt(v, 10);
630
- if (n < 0 || n > 59) {
631
- throw new Error('Invalid second: ' + n);
632
- }
633
- ctx.second = n;
634
- }
635
- },
636
- {
637
- token: 'S',
638
- regex: '\\d{1,2}',
639
- apply: v => {
640
- const n = parseInt(v, 10);
641
- if (n < 0 || n > 59) {
642
- throw new Error('Invalid second: ' + n);
643
- }
644
- ctx.second = n;
645
- }
646
- },
647
- {
648
- token: 's', // PHP-like seconds
649
- regex: '\\d{2}',
650
- apply: v => {
651
- const n = parseInt(v, 10);
652
- if (n < 0 || n > 59) {
653
- throw new Error('Invalid second: ' + n);
654
- }
655
- ctx.second = n;
656
- }
657
- },
658
- // Milliseconds
659
- {
660
- token: 'ms',
661
- regex: '\\d{1,3}',
662
- apply: v => {
663
- const n = parseInt(v, 10);
664
- if (n < 0 || n > 999) {
665
- throw new Error('Invalid millisecond: ' + n);
666
- }
667
- ctx.ms = n;
668
- }
669
- },
670
- // Weeks (parsed, but not used to construct the Date yet)
671
- {
672
- token: 'WWWW',
673
- regex: '\\d{1,2}',
674
- apply: v => {
675
- const n = parseInt(v, 10);
676
- if (n < 1 || n > 53) {
677
- throw new Error('Invalid week number: ' + n);
678
- }
679
- ctx.week = n;
680
- }
681
- },
682
- {
683
- token: 'WWW',
684
- regex: '\\d{1,2}',
685
- apply: v => {
686
- const n = parseInt(v, 10);
687
- if (n < 1 || n > 53) {
688
- throw new Error('Invalid week number: ' + n);
689
- }
690
- ctx.week = n;
691
- }
692
- },
693
- {
694
- token: 'WW',
695
- regex: '\\d{1,2}',
696
- apply: v => {
697
- const n = parseInt(v, 10);
698
- if (n < 1 || n > 53) {
699
- throw new Error('Invalid week number: ' + n);
700
- }
701
- ctx.week = n;
702
- }
703
- },
704
- {
705
- token: 'W',
706
- regex: '\\d{1,2}',
707
- apply: v => {
708
- const n = parseInt(v, 10);
709
- if (n < 1 || n > 53) {
710
- throw new Error('Invalid week number: ' + n);
711
- }
712
- ctx.week = n;
713
- }
714
- }
715
- ];
716
- // Sort tokens by length (desc) so we match 'YYYY' before 'YY', 'ms' before 'm'/'s', etc.
717
- const tokensByLength = [...tokenSpecs].sort((a, b) => b.token.length - a.token.length);
718
- let pattern = '';
719
- const applyFns = [];
720
- let i = 0;
721
- while (i < format.length) {
722
- let matchedToken = null;
723
- for (const spec of tokensByLength) {
724
- if (format.startsWith(spec.token, i)) {
725
- matchedToken = spec;
726
- break;
727
- }
728
- }
729
- if (matchedToken) {
730
- pattern += `(${matchedToken.regex})`;
731
- if (matchedToken.apply) {
732
- applyFns.push(matchedToken.apply);
733
- }
734
- else {
735
- // Still consume the capturing group, but ignore value
736
- applyFns.push(() => { });
737
- }
738
- i += matchedToken.token.length;
739
- }
740
- else {
741
- // Literal character
742
- pattern += escapeRegex(format[i]);
743
- i += 1;
744
- }
745
- }
746
- const fullRegex = new RegExp('^' + pattern + '$');
747
- const match = fullRegex.exec(input);
748
- if (!match) {
749
- throw new Error(`Date string "${input}" does not match format "${format}"`);
750
- }
751
- // Apply captured groups
752
- for (let idx = 1; idx < match.length; idx++) {
753
- const value = match[idx];
754
- const apply = applyFns[idx - 1];
755
- if (value != null && apply) {
756
- apply(value);
757
- }
758
- }
759
- // Build Date (local time)
760
- const date = new Date(ctx.year, ctx.month - 1, ctx.day, ctx.hour, ctx.minute, ctx.second, ctx.ms);
761
- // Strict validation: ensure Date didn't overflow (e.g. 31 Feb)
762
- if (date.getFullYear() !== ctx.year ||
763
- date.getMonth() !== ctx.month - 1 ||
764
- date.getDate() !== ctx.day ||
765
- date.getHours() !== ctx.hour ||
766
- date.getMinutes() !== ctx.minute ||
767
- date.getSeconds() !== ctx.second ||
768
- date.getMilliseconds() !== ctx.ms) {
769
- throw new Error('Invalid date produced from components');
770
- }
771
- // Optional: validate weekday if provided
772
- if (typeof ctx.weekday !== 'undefined') {
773
- const jsWeekday = date.getDay(); // 0 (Sunday) - 6 (Saturday)
774
- if (ctx.weekday === 0 || ctx.weekday === 7) {
775
- // If you decide EE is 0–6 or 1–7, adjust here as needed.
776
- // Not enforcing a strict rule beyond basic numeric check above.
777
- }
778
- // You could enforce consistency between ctx.weekday and jsWeekday here if you want.
779
- }
780
- return date;
781
- }
782
- /**
783
- * Compare 2 dates with a given precision.
784
- * @returns -1 if this < other, 0 if equal, 1 if this > other
785
- */
786
- static compare(date1, date2, unit = '') {
787
- var _a;
788
- const d1 = date1 instanceof bbnDateTool ? date1 : new bbnDateTool(date1);
789
- const d2 = date2 instanceof bbnDateTool ? date2 : new bbnDateTool(date2);
790
- const realUnit = unitsCorrespondence[unit] || null;
791
- // If no unit or unknown unit, fall back to timestamp comparison
792
- if (!realUnit) {
793
- if (d1.mtst < d2.mtst) {
794
- return -1;
795
- }
796
- if (d1.mtst > d2.mtst) {
797
- return 1;
798
- }
799
- return 0;
800
- }
801
- const order = ['y', 'm', 'd', 'h', 'i', 's'];
802
- // Compare step by step until the requested precision
803
- for (const u of order) {
804
- const key = (_a = getRow(units, un => un[0] === u)) === null || _a === void 0 ? void 0 : _a[1];
805
- const a = d2[key]();
806
- const b = d1[key]();
807
- if (a < b) {
808
- return -1;
809
- }
810
- if (a > b) {
811
- return 1;
812
- }
813
- // Stop when we've reached the desired unit
814
- if (u === realUnit) {
815
- break;
816
- }
817
- }
818
- return 0;
819
- }
820
- constructor(value, inputFormat = null) {
821
- _bbnDateTool_value.set(this, void 0);
822
- _bbnDateTool_isDuration.set(this, false);
823
- let t = typeof value;
824
- if (!value) {
825
- __classPrivateFieldSet(this, _bbnDateTool_value, new Date(), "f");
826
- }
827
- else if (inputFormat) {
828
- if (this.matchFormat(value, inputFormat)) {
829
- __classPrivateFieldSet(this, _bbnDateTool_value, bbnDateTool.parse(value, inputFormat), "f");
830
- }
831
- }
832
- else {
833
- if (t === 'number' || (isNumber(value) && value !== '')) {
834
- if ((value < 5000) && isNumber(inputFormat)) {
835
- value = Array.from(arguments);
836
- }
837
- else if (value < 10000000000) {
838
- value = value * 1000;
839
- }
840
- if (!Array.isArray(value)) {
841
- __classPrivateFieldSet(this, _bbnDateTool_value, new Date(value), "f");
842
- }
843
- }
844
- if (t === 'string') {
845
- for (const p of patterns) {
846
- const m = value.match(p.re);
847
- if (m) {
848
- const { year, month, day, hour, minute, second } = p.map(m);
849
- __classPrivateFieldSet(this, _bbnDateTool_value, new Date(year, month - 1, day, hour, minute, second, 0), "f");
850
- }
851
- }
852
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
853
- throw new Error('Invalid date string format: ' + value);
854
- }
855
- }
856
- else if (isDate(value)) {
857
- __classPrivateFieldSet(this, _bbnDateTool_value, value, "f");
858
- }
859
- else if (Array.isArray(value)) {
860
- __classPrivateFieldSet(this, _bbnDateTool_value, new Date(...value), "f");
861
- }
862
- }
863
- /*
864
- if (this.#value === undefined) {
865
- const obj = {};
866
- return new Proxy(this, {
867
- get: (target, prop) => {
868
- if (prop === 'isValid')
869
- return undefined;
870
- }
871
- });
872
- }*/
873
- }
874
- parse(input, format) {
875
- const d = bbnDateTool.parse(input, format);
876
- return new bbnDateTool(d);
877
- }
878
- matchFormat(value, format) {
879
- try {
880
- bbnDateTool.parse(value, format);
881
- return true;
882
- }
883
- catch (_a) {
884
- return false;
885
- }
886
- }
887
- toString() {
888
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f") ? this.format() : '';
889
- }
890
- year(v) {
891
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
892
- return undefined;
893
- }
894
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
895
- const d = this.copy();
896
- d.setFullYear(v);
897
- return new bbnDateTool(d);
898
- }
899
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getFullYear();
900
- }
901
- month(v) {
902
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
903
- return undefined;
904
- }
905
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
906
- const d = this.copy();
907
- d.setMonth(v - 1);
908
- return new bbnDateTool(d);
909
- }
910
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getMonth() + 1;
911
- }
912
- day(v) {
913
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
914
- return undefined;
915
- }
916
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
917
- const d = this.copy();
918
- d.setDate(v);
919
- return new bbnDateTool(d);
920
- }
921
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getDate();
922
- }
923
- hour(v) {
924
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
925
- return undefined;
926
- }
927
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
928
- const d = this.copy();
929
- d.setHours(v);
930
- return new bbnDateTool(d);
931
- }
932
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getHours();
933
- }
934
- minute(v) {
935
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
936
- return undefined;
937
- }
938
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
939
- const d = this.copy();
940
- d.setMinutes(v);
941
- return new bbnDateTool(d);
942
- }
943
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getMinutes();
944
- }
945
- second(v) {
946
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
947
- return undefined;
948
- }
949
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
950
- const d = this.copy();
951
- d.setSeconds(v);
952
- return new bbnDateTool(d);
953
- }
954
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getSeconds();
955
- }
956
- weekday(v, past = false) {
957
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
958
- return undefined;
959
- }
960
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
961
- return this.setWeekday(v, past);
962
- }
963
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getDay();
964
- }
965
- /**
966
- * Returns the ISO-8601 week number of this date.
967
- * Week starts on Monday, and week 1 is the week with Jan 4.
968
- *
969
- * @returns {number} ISO week number (1–53)
970
- */
971
- week() {
972
- // Copy date in UTC to avoid timezone issues
973
- const d = new Date(Date.UTC(this.year(), this.month() - 1, this.day()));
974
- // Set to nearest Thursday (ISO anchor)
975
- // (Thursday = day 4, because Sunday=0, Monday=1,...)
976
- const dayNum = d.getUTCDay() || 7; // make Sunday = 7
977
- // Move date to Thursday of this week
978
- d.setUTCDate(d.getUTCDate() + (4 - dayNum));
979
- // First week of the year is the week with Jan 4 in it
980
- const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
981
- // Calculate full weeks between the dates
982
- const weekNo = Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
983
- return weekNo;
984
- }
985
- get tst() {
986
- return Math.ceil(__classPrivateFieldGet(this, _bbnDateTool_value, "f").getTime() / 1000);
987
- }
988
- get mtst() {
989
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getTime();
990
- }
991
- get YYYY() {
992
- return this.year().toString();
993
- }
994
- get YY() {
995
- return substr(this.year().toString(), 2, 2);
996
- }
997
- get MMMM() {
998
- const opt = {
999
- month: 'long',
1000
- };
1001
- const d = new Intl.DateTimeFormat([bbn.env.lang, ...navigator.languages], opt);
1002
- return d.format(__classPrivateFieldGet(this, _bbnDateTool_value, "f"));
1003
- }
1004
- get MMM() {
1005
- const opt = {
1006
- month: 'short',
1007
- };
1008
- const d = new Intl.DateTimeFormat([bbn.env.lang, ...navigator.languages], opt);
1009
- return d.format(__classPrivateFieldGet(this, _bbnDateTool_value, "f"));
1010
- }
1011
- get MM() {
1012
- const m = parseInt(this.month().toString());
1013
- return m < 10 ? '0' + m.toString() : m.toString();
1014
- }
1015
- get M() {
1016
- return this.month().toString();
1017
- }
1018
- get EE() {
1019
- return this.weekday().toString();
1020
- }
1021
- get DD() {
1022
- const d = parseInt(this.day().toString());
1023
- return d < 10 ? '0' + d.toString() : d.toString();
1024
- }
1025
- get d() {
1026
- return this.day().toString();
1027
- }
1028
- get dddd() {
1029
- const opt = {
1030
- weekday: 'long'
1031
- };
1032
- const d = new Intl.DateTimeFormat([bbn.env.lang, ...navigator.languages], opt);
1033
- return d.format(__classPrivateFieldGet(this, _bbnDateTool_value, "f"));
1034
- }
1035
- get ddd() {
1036
- const opt = {
1037
- weekday: 'short'
1038
- };
1039
- const d = new Intl.DateTimeFormat([bbn.env.lang, ...navigator.languages], opt);
1040
- return d.format(__classPrivateFieldGet(this, _bbnDateTool_value, "f"));
1041
- }
1042
- get D() {
1043
- return this.day().toString();
1044
- }
1045
- get HH() {
1046
- const h = parseInt(this.hour().toString());
1047
- return h < 10 ? '0' + h.toString() : h.toString();
1048
- }
1049
- get H() {
1050
- return this.hour().toString();
1051
- }
1052
- get II() {
1053
- const i = parseInt(this.minute().toString());
1054
- return i < 10 ? '0' + i.toString() : i.toString();
1055
- }
1056
- get mm() {
1057
- const i = parseInt(this.minute().toString());
1058
- return i < 10 ? '0' + i.toString() : i.toString();
1059
- }
1060
- get I() {
1061
- return this.minute().toString();
1062
- }
1063
- get SS() {
1064
- const s = parseInt(this.second().toString());
1065
- return s < 10 ? '0' + s.toString() : s.toString();
1066
- }
1067
- get S() {
1068
- return this.second().toString();
1069
- }
1070
- get WW() {
1071
- const y = parseInt(this.year().toString());
1072
- const firstDayOfYear = new Date(y, 0, 1);
1073
- const pastDaysOfYear = (__classPrivateFieldGet(this, _bbnDateTool_value, "f").getTime() - firstDayOfYear.getTime()) / 86400000;
1074
- return String(Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7)).padStart(2, '0');
1075
- }
1076
- get isValid() {
1077
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f") !== undefined;
1078
- }
1079
- dateFromFormat(value, unit) {
1080
- const d = new Date();
1081
- return d;
1082
- }
1083
- date(v) {
1084
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
1085
- return this.parse(v, 'Y-m-d');
1086
- }
1087
- return this.format('Y-m-d');
1088
- }
1089
- datetime(v) {
1090
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
1091
- return this.parse(v, 'Y-m-d H:i:s');
1092
- }
1093
- return this.format('Y-m-d H:i:s');
1094
- }
1095
- time(v) {
1096
- if (0 in arguments && (v !== undefined) && !(v instanceof Event)) {
1097
- return this.parse(v, 'H:i:s');
1098
- }
1099
- return this.format('H:i:s');
1100
- }
1101
- fdate(long = false, withTime = false, weekday = false) {
1102
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
1103
- return '';
1104
- }
1105
- const opt = Object.assign(Object.assign({ year: 'numeric', month: long ? 'long' : 'numeric', day: 'numeric' }, (weekday ? { weekday: (long ? 'long' : 'short') } : {})), (withTime ? { hour: (long ? '2-digit' : 'numeric'), minute: '2-digit' } : {}));
1106
- const d = new Intl.DateTimeFormat([bbn.env.lang, ...navigator.languages], opt);
1107
- return d.format(__classPrivateFieldGet(this, _bbnDateTool_value, "f"));
1108
- }
1109
- ftime(withSeconds = false) {
1110
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
1111
- return '';
1112
- }
1113
- const opt = {
1114
- hour: '2-digit',
1115
- minute: '2-digit',
1116
- };
1117
- if (withSeconds) {
1118
- opt.second = '2-digit';
1119
- }
1120
- const t = new Intl.DateTimeFormat([bbn.env.lang, ...navigator.languages], opt);
1121
- return t.format(__classPrivateFieldGet(this, _bbnDateTool_value, "f"));
1122
- }
1123
- format(format = 'YYYY-MM-DD HH:II:SS') {
1124
- let str = '';
1125
- if (format) {
1126
- const reg = new RegExp('(\[|\]|' + Object.keys(unitsCorrespondence).join('|') + ')', 'g');
1127
- let opened = 0;
1128
- const parts = format.split(reg);
1129
- each(parts, (part) => {
1130
- if (part === '[') {
1131
- opened++;
1132
- return;
1133
- }
1134
- else if (part === ']') {
1135
- opened--;
1136
- return;
1137
- }
1138
- if (opened > 0) {
1139
- str += part;
1140
- return;
1141
- }
1142
- if (part in unitsCorrespondence) {
1143
- if (part in this && isPrimitive(this[part])) {
1144
- str += this[part];
1145
- }
1146
- else {
1147
- const suffix = formatsMap[unitsCorrespondence[part]];
1148
- str += this[suffix];
1149
- }
1150
- }
1151
- else {
1152
- str += part;
1153
- }
1154
- });
1155
- }
1156
- return str;
1157
- }
1158
- unix(ms = false) {
1159
- if (typeof ms === 'number') {
1160
- const date = this.copy();
1161
- date.setTime(ms * 1000);
1162
- return new bbnDateTool(date);
1163
- }
1164
- if (__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
1165
- if (ms) {
1166
- return __classPrivateFieldGet(this, _bbnDateTool_value, "f").getTime();
1167
- }
1168
- else {
1169
- return Math.floor(__classPrivateFieldGet(this, _bbnDateTool_value, "f").getTime() / 1000);
1170
- }
1171
- }
1172
- return 0;
1173
- }
1174
- sql(noTime = false) {
1175
- if (!__classPrivateFieldGet(this, _bbnDateTool_value, "f")) {
1176
- return '';
1177
- }
1178
- return noTime
1179
- ? this.format('YYYY-MM-DD')
1180
- : this.format('YYYY-MM-DD HH:II:SS');
1181
- }
1182
- inLeapYear() {
1183
- if (this.isValid) {
1184
- const year = __classPrivateFieldGet(this, _bbnDateTool_value, "f").getFullYear();
1185
- return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
1186
- }
1187
- return false;
1188
- }
1189
- daysInMonth() {
1190
- if (this.isValid) {
1191
- switch (__classPrivateFieldGet(this, _bbnDateTool_value, "f").getMonth()) {
1192
- case 1:
1193
- if (__classPrivateFieldGet(this, _bbnDateTool_value, "f").getFullYear() % 4 === 0) {
1194
- return 29;
1195
- }
1196
- else {
1197
- return 28;
1198
- }
1199
- case 0:
1200
- case 3:
1201
- case 5:
1202
- case 8:
1203
- case 10:
1204
- return 30;
1205
- default:
1206
- return 31;
1207
- }
1208
- }
1209
- }
1210
- valueOf() {
1211
- return this.mtst;
1212
- }
1213
- /**
1214
- * Compare this date to another date with a given precision.
1215
- * @returns -1 if this < other, 0 if equal, 1 if this > other
1216
- */
1217
- compare(date, unit = '') {
1218
- return bbnDateTool.compare(this, date, unit);
1219
- }
1220
- add(value, unit = 'd') {
1221
- const date = __classPrivateFieldGet(this, _bbnDateTool_value, "f") ? new Date(__classPrivateFieldGet(this, _bbnDateTool_value, "f").getTime()) : new Date();
1222
- if (unitsCorrespondence[unit]) {
1223
- const realUnit = unitsCorrespondence[unit];
1224
- const suffix = realUnit === 'y' ? 'FullYear' : unitsMap[realUnit];
1225
- const getter = 'get' + suffix;
1226
- const setter = 'set' + suffix;
1227
- date[setter](date[getter]() + value);
1228
- return new bbnDateTool(date);
1229
- }
1230
- return null;
1231
- }
1232
- subtract(value, unit) {
1233
- return this.add(-value, unit);
1234
- }
1235
- isBefore(date, unit = '') {
1236
- return this.compare(date, unit) === -1;
1237
- }
1238
- isAfter(date, unit = 'day') {
1239
- return this.compare(date, unit) === 1;
1240
- }
1241
- isSame(date, unit = 'day') {
1242
- return this.compare(date, unit) === 0;
1243
- }
1244
- isAfterOrSame(date, unit = '') {
1245
- return [0, 1].includes(this.compare(date, unit));
1246
- }
1247
- isBeforeOrSame(date, unit = '') {
1248
- return [-1, 0].includes(this.compare(date, unit));
1249
- }
1250
- fromNow(unit = '') {
1251
- const date = new Date();
1252
- const chosenUnit = unitsCorrespondence[unit] || this.guessUnit(this.diff(date));
1253
- const diff = this.diff(date, chosenUnit);
1254
- const rtf = new Intl.RelativeTimeFormat([bbn.env.lang, ...navigator.languages], { numeric: "auto" });
1255
- // FORCED UNIT MODE
1256
- const match = getRow(units, d => d[0] === chosenUnit);
1257
- if (!match) {
1258
- throw new Error('Invalid unit for fromDate: ' + unit);
1259
- }
1260
- return rtf.format(diff, match[1]);
1261
- }
1262
- fromDate(date, unit = '') {
1263
- const chosenUnit = unitsCorrespondence[unit] || this.guessUnit(this.diff(date));
1264
- const diff = this.diff(date, chosenUnit);
1265
- return diff > 0 ? _('%d %s before', diff, unit) : (diff < 0 ? _('%d %s after', -diff, unit) : _("The same %s", unit));
1266
- }
1267
- guessUnit(valueInMs) {
1268
- const absDiff = Math.abs(valueInMs);
1269
- for (const [shortUnit, rtfUnit, ms] of units) {
1270
- if ((absDiff >= ms) || (rtfUnit === "second")) {
1271
- return shortUnit;
1272
- }
1273
- }
1274
- }
1275
- diff(date, unit = '', abs = false) {
1276
- const target = (date instanceof bbnDateTool) ? date.mtst : new Date(date).getTime();
1277
- const now = this.mtst;
1278
- let diff = now - target;
1279
- if (abs) {
1280
- diff = Math.abs(diff);
1281
- }
1282
- if (!unit) {
1283
- return diff;
1284
- }
1285
- const realUnit = unitsCorrespondence[unit];
1286
- const match = getRow(units, d => d[0] === realUnit);
1287
- if (!match) {
1288
- throw new Error('Invalid unit for diff: ' + unit);
1289
- }
1290
- const [u, rtfUnit, ms] = match;
1291
- return Math.round(diff / ms);
1292
- }
1293
- calendar(format) {
1294
- let str = '';
1295
- if (format) {
1296
- }
1297
- return str;
1298
- }
1299
- getWeekday(n, mode = 'long', locale) {
1300
- if (!mode) {
1301
- const letter = this.getWeekday(n, 'narrow', locale);
1302
- const abbr = this.getWeekday(n, 'short', locale);
1303
- const full = this.getWeekday(n, 'long', locale);
1304
- return {
1305
- letter,
1306
- abbr,
1307
- full,
1308
- long: full,
1309
- short: abbr,
1310
- narrow: letter
1311
- };
1312
- }
1313
- let m;
1314
- if (mode === 'letter') {
1315
- m = 'narrow';
1316
- }
1317
- else if (mode === 'abbr') {
1318
- m = 'short';
1319
- }
1320
- else if (mode === 'full') {
1321
- m = 'long';
1322
- }
1323
- else if (!['long', 'short', 'narrow'].includes(mode)) {
1324
- throw new Error('Invalid mode for getWeekDay: ' + mode + '. Allowed values are "long", "short", "narrow", "letter", "abbr", "full".');
1325
- }
1326
- else {
1327
- m = mode;
1328
- }
1329
- // Create a date with the right weekday
1330
- // 2023-01-01 was a Sunday → base for offset
1331
- const base = new Date(2023, 0, 1 + n);
1332
- return base.toLocaleDateString([locale || bbn.env.lang, ...navigator.languages], { weekday: m });
1333
- }
1334
- getWeekdayIndex(name, locale) {
1335
- const loc = locale || bbn.env.lang;
1336
- const input = name.trim().toLowerCase();
1337
- // Build a localized map only once per locale (optional optimization)
1338
- const langs = [loc, ...navigator.languages];
1339
- for (let i = 0; i < langs.length; i++) {
1340
- if (!langs[i]) {
1341
- continue;
1342
- }
1343
- const formatter = new Intl.DateTimeFormat(langs[i], { weekday: "long" });
1344
- // Generate localized weekday names for Sun → Sat
1345
- for (let i = 0; i < 7; i++) {
1346
- // 2023-01-01 was Sunday
1347
- const date = new Date(2023, 0, 1 + i);
1348
- const localized = formatter.format(date).toLowerCase();
1349
- if (localized === input) {
1350
- return i; // JS weekday number
1351
- }
1352
- }
1353
- }
1354
- throw new Error(`Unknown weekday name '${name}' for locale '${loc}'`);
1355
- }
1356
- /**
1357
- * Returns a NEW date that is the next (or previous if past=true)
1358
- * occurrence of the given weekday, starting from this.#value.
1359
- *
1360
- * @param {number|string} weekday - Weekday index (0=Sunday…6=Saturday)
1361
- * or a localized weekday name.
1362
- * @param {boolean} past - If true → return previous occurrence instead of next.
1363
- * @param {string} [locale] - Optional locale for weekday names.
1364
- */
1365
- setWeekday(weekday, past = false, locale) {
1366
- let targetDay;
1367
- if (typeof weekday === "string") {
1368
- // Use your previously defined reverse method:
1369
- weekday = this.getWeekdayIndex(weekday, locale);
1370
- }
1371
- // --- Normalize weekday ---
1372
- if (typeof weekday === "number") {
1373
- if (weekday < 0 || weekday > 6) {
1374
- throw new RangeError("weekday number must be between 0 and 6");
1375
- }
1376
- targetDay = weekday;
1377
- }
1378
- else {
1379
- throw new TypeError("weekday must be a number (0–6) or a string");
1380
- }
1381
- const currentDay = this.weekday(); // JS weekday (0–6)
1382
- let diff;
1383
- if (!past) {
1384
- // ---------- NEXT occurrence ----------
1385
- diff = (targetDay - currentDay + 7) % 7;
1386
- if (diff === 0) {
1387
- diff = 7; // next week if same day
1388
- }
1389
- }
1390
- else {
1391
- // ---------- PREVIOUS occurrence ----------
1392
- diff = (currentDay - targetDay + 7) % 7;
1393
- if (diff === 0) {
1394
- diff = 7; // previous week if same day
1395
- }
1396
- diff = -diff;
1397
- }
1398
- const d = this.copy();
1399
- d.setDate(d.getDate() + diff);
1400
- return new bbnDateTool(d);
1401
- }
1402
- copy() {
1403
- return new Date(__classPrivateFieldGet(this, _bbnDateTool_value, "f").getTime());
1404
- }
1405
- clone() {
1406
- return new bbnDateTool(__classPrivateFieldGet(this, _bbnDateTool_value, "f") ? new Date(__classPrivateFieldGet(this, _bbnDateTool_value, "f").getTime()) : undefined);
1407
- }
1408
- /**
1409
- * Returns a NEW bbnDateTool at the start of the given unit.
1410
- * Units: year, month, week, day, hour, minute, second
1411
- */
1412
- startOf(unit = "d") {
1413
- const u = unitsCorrespondence[unit];
1414
- if (!u) {
1415
- throw new Error('Invalid unit for startOf: ' + unit);
1416
- }
1417
- let d;
1418
- switch (u) {
1419
- case "y":
1420
- d = new Date(this.year(), 0, 1, 0, 0, 0, 0);
1421
- break;
1422
- case "m":
1423
- d = new Date(this.year(), this.month() - 1, 1, 0, 0, 0, 0);
1424
- break;
1425
- case "w": {
1426
- // Week starting Monday:
1427
- // JS getDay(): 0 (Sun) .. 6 (Sat)
1428
- const current = new Date(this.year(), this.month() - 1, this.day(), this.hour(), this.minute(), this.second(), 0);
1429
- const wd = current.getDay(); // 0..6
1430
- const diffToMonday = (wd + 6) % 7; // 0 for Monday, 6 for Sunday
1431
- d = new Date(current.getFullYear(), current.getMonth(), current.getDate() - diffToMonday, 0, 0, 0, 0);
1432
- break;
1433
- }
1434
- case "d":
1435
- d = new Date(this.year(), this.month() - 1, this.day(), 0, 0, 0, 0);
1436
- break;
1437
- case "h":
1438
- d = new Date(this.year(), this.month() - 1, this.day(), this.hour(), 0, 0, 0);
1439
- break;
1440
- case "i":
1441
- d = new Date(this.year(), this.month() - 1, this.day(), this.hour(), this.minute(), 0, 0);
1442
- break;
1443
- case "s":
1444
- d = new Date(this.year(), this.month() - 1, this.day(), this.hour(), this.minute(), this.second(), 0);
1445
- break;
1446
- default:
1447
- throw new Error('Invalid unit for startOf: ' + unit);
1448
- }
1449
- return new bbnDateTool(d);
1450
- }
1451
- /**
1452
- * Returns a NEW bbnDateTool at the end of the given unit.
1453
- * Units: year, month, week, day, hour, minute, second
1454
- */
1455
- endOf(unit = "d") {
1456
- const u = unitsCorrespondence[unit];
1457
- if (!u) {
1458
- throw new Error('Invalid unit for endOf: ' + unit);
1459
- }
1460
- let d;
1461
- switch (u) {
1462
- case "y":
1463
- // Dec 31, 23:59:59.999
1464
- d = new Date(this.year(), 11, 31, 23, 59, 59, 999);
1465
- break;
1466
- case "m":
1467
- // Day 0 of next month = last day of this month
1468
- d = new Date(this.year(), this.month(), 0, 23, 59, 59, 999);
1469
- break;
1470
- case "w": {
1471
- // End of week (starting Monday) = startOf('week') + 6 days, at 23, 59, 59, 999
1472
- const start = this.startOf("w");
1473
- const base = new Date(start.year(), start.month() - 1, start.day(), 23, 59, 59, 999);
1474
- base.setDate(base.getDate() + 6);
1475
- d = base;
1476
- break;
1477
- }
1478
- case "day":
1479
- d = new Date(this.year(), this.month() - 1, this.day(), 23, 59, 59, 999);
1480
- break;
1481
- case "hour":
1482
- d = new Date(this.year(), this.month() - 1, this.day(), this.hour(), 59, 59, 999);
1483
- break;
1484
- case "minute":
1485
- d = new Date(this.year(), this.month() - 1, this.day(), this.hour(), this.minute(), 59, 999);
1486
- break;
1487
- case "second":
1488
- d = new Date(this.year(), this.month() - 1, this.day(), this.hour(), this.minute(), this.second(), 999);
1489
- break;
1490
- default:
1491
- d = new Date(this.mtst);
1492
- }
1493
- return new bbnDateTool(d);
1494
- }
1495
- duration(num, unit = 's') {
1496
- return new bbnDateDuration(num, unit);
1497
- }
1498
- }
1499
- _bbnDateTool_value = new WeakMap(), _bbnDateTool_isDuration = new WeakMap();
1500
- function generatorFunction(value, inputFormat = null) {
1501
- if (value instanceof bbnDateTool) {
1502
- return value;
1503
- }
1504
- return new bbnDateTool(value, inputFormat);
1505
- }
1506
- export default generatorFunction;