@acorex/core 19.12.0-next.1 → 19.12.0-next.3
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/date-time/index.d.ts +5 -5
- package/date-time/lib/calendar.service.d.ts +8 -3
- package/date-time/lib/dateTime.config.d.ts +1 -1
- package/date-time/lib/datetime.pipe.d.ts +2 -1
- package/date-time/lib/{datetime.class.d.ts → datetime.types.d.ts} +2 -2
- package/date-time/lib/formatters/date.formatter.d.ts +12 -0
- package/date-time/lib/formatters/{datetime-formatter.d.ts → datetime.formatter.d.ts} +3 -1
- package/date-time/lib/formatters/time.formatter.d.ts +12 -0
- package/date-time/lib/{georgian.calendar.d.ts → gregorian.calendar.d.ts} +2 -2
- package/date-time/lib/{jalali.calendar.d.ts → solar-hijri.calendar.d.ts} +8 -8
- package/events/index.d.ts +0 -1
- package/fesm2022/acorex-core-date-time.mjs +305 -132
- package/fesm2022/acorex-core-date-time.mjs.map +1 -1
- package/fesm2022/acorex-core-events.mjs +1 -7
- package/fesm2022/acorex-core-events.mjs.map +1 -1
- package/fesm2022/acorex-core-format.mjs +47 -33
- package/fesm2022/acorex-core-format.mjs.map +1 -1
- package/fesm2022/acorex-core-locale-en-AU.profile-BW-_9tgT.mjs +64 -0
- package/fesm2022/acorex-core-locale-en-AU.profile-BW-_9tgT.mjs.map +1 -0
- package/fesm2022/acorex-core-locale.mjs +341 -0
- package/fesm2022/acorex-core-locale.mjs.map +1 -0
- package/fesm2022/acorex-core-translation.mjs +12 -4
- package/fesm2022/acorex-core-translation.mjs.map +1 -1
- package/format/index.d.ts +2 -2
- package/format/lib/format.directive.d.ts +1 -1
- package/format/lib/format.module.d.ts +3 -3
- package/locale/README.md +3 -0
- package/locale/index.d.ts +8 -0
- package/locale/lib/formatters/currency.formatter.d.ts +10 -0
- package/locale/lib/locale-profile-provider.service.d.ts +24 -0
- package/locale/lib/locale.config.d.ts +5 -0
- package/locale/lib/locale.module.d.ts +7 -0
- package/locale/lib/locale.service.d.ts +20 -0
- package/locale/lib/locale.types.d.ts +61 -0
- package/locale/lib/profiles/en-AU.profile.d.ts +2 -0
- package/locale/lib/profiles/en-US.profile.d.ts +2 -0
- package/locale/lib/profiles/fa-IR.profile.d.ts +2 -0
- package/package.json +5 -1
- package/translation/lib/translation.service.d.ts +1 -0
- package/types/README.md +2 -2
- package/events/lib/event.type.d.ts +0 -5
- package/i18n/en/common.json +0 -191
- package/i18n/fa/common.json +0 -190
- /package/date-time/lib/formatters/{time-duration-formatter.d.ts → time-duration.formatter.d.ts} +0 -0
- /package/date-time/lib/formatters/{timeleft-formatter.d.ts → timeleft.formatter.d.ts} +0 -0
- /package/format/lib/formatters/{number-formatter.d.ts → number.formatter.d.ts} +0 -0
- /package/format/lib/formatters/{string-formatter.d.ts → string.formatter.d.ts} +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { AXEventService } from '@acorex/core/events';
|
2
2
|
import * as i0 from '@angular/core';
|
3
3
|
import { InjectionToken, inject, Injectable, Pipe, NgModule } from '@angular/core';
|
4
4
|
import { BehaviorSubject, Subject } from 'rxjs';
|
@@ -6,8 +6,9 @@ import { AX_GLOBAL_CONFIG } from '@acorex/core/config';
|
|
6
6
|
import { defaults, orderBy, set, isNil } from 'lodash-es';
|
7
7
|
import { isBrowser } from '@acorex/core/platform';
|
8
8
|
import { translateSync } from '@acorex/core/translation';
|
9
|
+
import { AXLocaleEvents, AXLocaleService } from '@acorex/core/locale';
|
9
10
|
import * as i1 from '@acorex/core/format';
|
10
|
-
import { AXFormatModule } from '@acorex/core/format';
|
11
|
+
import { AXFormatService, AXFormatModule } from '@acorex/core/format';
|
11
12
|
|
12
13
|
class AXCalendar {
|
13
14
|
/**
|
@@ -19,9 +20,9 @@ class AXCalendar {
|
|
19
20
|
get weekend() {
|
20
21
|
return this._config.weekend;
|
21
22
|
}
|
22
|
-
get formats() {
|
23
|
-
|
24
|
-
}
|
23
|
+
// public get formats(): AXDateTimeDisplayFormats {
|
24
|
+
// return this._config.formats;
|
25
|
+
// }
|
25
26
|
get weekdays() {
|
26
27
|
return this._config.weekdays;
|
27
28
|
}
|
@@ -36,38 +37,74 @@ class AXDateTime {
|
|
36
37
|
constructor(value, calendar) {
|
37
38
|
//TODO: remove unused items
|
38
39
|
this._formatKeys = {
|
39
|
-
|
40
|
+
// 0 1 ... 58 59
|
40
41
|
s: () => this.date.getSeconds().toString(),
|
41
|
-
//
|
42
|
-
|
42
|
+
// 00 01 ... 58 59
|
43
|
+
ss: () => this.pad(this.date.getSeconds(), 2),
|
44
|
+
// 0 1 ... 5 6 day of week ***
|
45
|
+
d: () => (this.calendar.dayOfWeek(this.date) - 1).toString(),
|
46
|
+
// Su Mo ... Fr Sa ***
|
47
|
+
dd: () => translateSync(`dateTime.weekdays.short.${this.calendar.weekdays[this.calendar.dayOfWeek(this.date) - 1]}`),
|
48
|
+
ddd: () => translateSync(`dateTime.weekdays.short.${this.calendar.weekdays[this.calendar.dayOfWeek(this.date) - 1]}`),
|
49
|
+
// Sunday Monday ... Friday Saturday
|
50
|
+
dddd: () => translateSync(`dateTime.weekdays.long.${this.calendar.weekdays[this.calendar.dayOfWeek(this.date) - 1]}`),
|
51
|
+
// 1 2 ... 30 31
|
52
|
+
D: () => this.calendar.dayOfMonth(this.date).toString(),
|
53
|
+
// 01 02 ... 30 31 day of month
|
43
54
|
DD: () => this.pad(this.calendar.dayOfMonth(this.date), 2),
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
//
|
49
|
-
|
50
|
-
|
55
|
+
// 1 2 ... 364 365
|
56
|
+
DDD: () => this.calendar.dayOfYear(this.date).toString(),
|
57
|
+
// 001 002 ... 364 365 day of year
|
58
|
+
DDDD: () => this.pad(this.calendar.dayOfYear(this.date), 3),
|
59
|
+
// 1 2 ... 52 53
|
60
|
+
w: () => this.calendar.weekOfYear(this.date).toString(),
|
61
|
+
// 01 02 ... 52 53
|
62
|
+
ww: () => this.pad(this.calendar.weekOfYear(this.date), 2),
|
63
|
+
// 1 2 ... 11 12
|
64
|
+
M: () => this.calendar.monthOfYear(this.date).toString(),
|
65
|
+
// 01 02 ... 11 12
|
51
66
|
MM: () => this.pad(this.calendar.monthOfYear(this.date), 2),
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
67
|
+
// Jan Feb ... Nov Dec
|
68
|
+
MMM: () => translateSync(`dateTime.months.${this.calendar.name()}.short.${this.calendar.monthOfYear(this.date) - 1}`),
|
69
|
+
// January February ... November December
|
70
|
+
MMMM: () => translateSync(`dateTime.months.${this.calendar.name()}.long.${this.calendar.monthOfYear(this.date) - 1}`),
|
71
|
+
// 1 2 ... 7
|
72
|
+
E: () => this.calendar.dayOfWeek(this.date).toString(),
|
73
|
+
// 01 02 ... 07
|
74
|
+
EE: () => this.pad(this.calendar.dayOfWeek(this.date), 2),
|
75
|
+
// Sun Mon ... Sat
|
76
|
+
EEE: () => translateSync(`dateTime.weekdays.short.${this.calendar.weekdays[this.calendar.dayOfWeek(this.date) - 1]}`),
|
77
|
+
// Sunday Monday ... Saturday
|
78
|
+
EEEE: () => translateSync(`dateTime.weekdays.long.${this.calendar.weekdays[this.calendar.dayOfWeek(this.date) - 1]}`),
|
79
|
+
// 1 2 ... 2020 ...
|
80
|
+
y: () => this.calendar.year(this.date).toString(),
|
81
|
+
// 70 71 ... 29 30
|
60
82
|
yy: () => this.pad(this.calendar.year(this.date), 4).substring(2),
|
61
83
|
YY: () => this.pad(this.calendar.year(this.date), 4).substring(2),
|
62
|
-
//
|
63
|
-
|
64
|
-
|
65
|
-
//
|
66
|
-
|
84
|
+
// 1970 1971 ... 2029 2030
|
85
|
+
yyyy: () => this.pad(this.calendar.year(this.date), 4),
|
86
|
+
YYYY: () => this.pad(this.calendar.year(this.date), 4),
|
87
|
+
// 0 1 ... 58 59
|
88
|
+
m: () => this.date.getMinutes().toString(),
|
89
|
+
// 00 01 ... 58 59
|
90
|
+
mm: () => this.pad(this.date.getMinutes(), 2),
|
91
|
+
// 0 1 ... 11 12
|
67
92
|
h: () => (this.date.getHours() % 12 || 12).toString(),
|
93
|
+
// 00 01 ... 11 12
|
94
|
+
hh: () => this.pad(this.date.getHours() % 12 || 12, 2),
|
95
|
+
// 0 1 ... 23 24
|
96
|
+
H: () => this.date.getHours().toString(),
|
97
|
+
// 00 01 ... 23 24
|
98
|
+
HH: () => this.pad(this.date.getHours(), 2),
|
99
|
+
// TODO: i18n
|
100
|
+
// AM PM
|
101
|
+
A: () => (this.date.getHours() < 12 ? 'AM' : 'PM').toUpperCase(),
|
102
|
+
// am pm
|
103
|
+
a: () => (this.date.getHours() < 12 ? 'am' : 'pm').toLowerCase(),
|
104
|
+
// TODO: review
|
105
|
+
Z: () => '',
|
106
|
+
ZZZZ: () => '',
|
68
107
|
//
|
69
|
-
A: () => (this.date.getHours() < 12 ? 'am' : 'pm'),
|
70
|
-
a: () => (this.date.getHours() < 12 ? 'am' : 'pm'),
|
71
108
|
date: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'shortDate')),
|
72
109
|
shortDate: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'shortDate')),
|
73
110
|
longDate: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'longDate')),
|
@@ -78,7 +115,7 @@ class AXDateTime {
|
|
78
115
|
//
|
79
116
|
datetime: (options) => this.format('date time', { locale: options.locale }),
|
80
117
|
};
|
81
|
-
this._language = () => (isBrowser() ? navigator.language : 'en-
|
118
|
+
this._language = () => (isBrowser() ? navigator.language : 'en-US');
|
82
119
|
this._calendar = calendar;
|
83
120
|
this._date = value;
|
84
121
|
}
|
@@ -140,8 +177,11 @@ class AXDateTime {
|
|
140
177
|
const re = new RegExp(orderBy(Object.keys(this._formatKeys), (c) => c.length, ['desc']).join('|'), 'gi');
|
141
178
|
return format.replace(re, (matched) => {
|
142
179
|
const f = this._formatKeys[matched];
|
143
|
-
|
144
|
-
|
180
|
+
if (f && typeof f === 'function') {
|
181
|
+
const r = f(effectiveOptions);
|
182
|
+
return r;
|
183
|
+
}
|
184
|
+
return matched;
|
145
185
|
});
|
146
186
|
}
|
147
187
|
getDateTimeFormatByLocale(locale, style) {
|
@@ -279,6 +319,8 @@ class AXDateTimeRange {
|
|
279
319
|
minutes: 0,
|
280
320
|
hours: 0,
|
281
321
|
days: 0,
|
322
|
+
// NOTE: Calculating exact calendar months/years component is complex
|
323
|
+
// from milliseconds alone. We'll set these to 0.
|
282
324
|
months: 0,
|
283
325
|
years: 0,
|
284
326
|
total: {
|
@@ -288,46 +330,54 @@ class AXDateTimeRange {
|
|
288
330
|
hours: 0,
|
289
331
|
days: 0,
|
290
332
|
weeks: 0,
|
333
|
+
// NOTE: total.months and total.years are approximate based on average lengths
|
291
334
|
months: 0,
|
292
335
|
years: 0,
|
293
336
|
},
|
294
337
|
};
|
295
|
-
|
296
|
-
const
|
297
|
-
const
|
298
|
-
const
|
299
|
-
const
|
300
|
-
const
|
301
|
-
const
|
338
|
+
// Constants for time units in milliseconds
|
339
|
+
const ONE_MILLISECOND = 1;
|
340
|
+
const ONE_SECOND = 1000 * ONE_MILLISECOND;
|
341
|
+
const ONE_MINUTE = 60 * ONE_SECOND;
|
342
|
+
const ONE_HOUR = 60 * ONE_MINUTE;
|
343
|
+
const ONE_DAY = 24 * ONE_HOUR;
|
344
|
+
const ONE_WEEK = 7 * ONE_DAY;
|
345
|
+
// Average lengths for approximate total months/years
|
346
|
+
const ONE_YEAR_AVG = 365.25 * ONE_DAY;
|
347
|
+
const ONE_MONTH_AVG = ONE_YEAR_AVG / 12;
|
302
348
|
const startTime = this._startTime.date.getTime();
|
303
349
|
const endTime = this._endTime.date.getTime();
|
350
|
+
// Calculate the absolute difference in milliseconds
|
304
351
|
const diff = Math.abs(endTime - startTime);
|
305
|
-
//
|
352
|
+
// --- Calculate Total Durations ---
|
306
353
|
result.total.miliseconds = diff;
|
307
|
-
result.total.seconds =
|
308
|
-
result.total.minutes =
|
309
|
-
result.total.hours =
|
310
|
-
result.total.days =
|
311
|
-
result.total.weeks =
|
312
|
-
//
|
313
|
-
|
314
|
-
//
|
315
|
-
|
316
|
-
//
|
317
|
-
|
318
|
-
//
|
319
|
-
//
|
320
|
-
result.
|
321
|
-
|
322
|
-
//
|
323
|
-
result.
|
324
|
-
|
325
|
-
|
326
|
-
result.
|
327
|
-
//
|
328
|
-
|
329
|
-
result.
|
330
|
-
|
354
|
+
result.total.seconds = diff / ONE_SECOND;
|
355
|
+
result.total.minutes = diff / ONE_MINUTE;
|
356
|
+
result.total.hours = diff / ONE_HOUR;
|
357
|
+
result.total.days = diff / ONE_DAY; // Includes fractional days
|
358
|
+
result.total.weeks = diff / ONE_WEEK; // Includes fractional weeks
|
359
|
+
result.total.months = diff / ONE_MONTH_AVG; // Approximate
|
360
|
+
result.total.years = diff / ONE_YEAR_AVG; // Approximate
|
361
|
+
// --- Calculate Component Parts ---
|
362
|
+
let remainingMillis = diff;
|
363
|
+
// Calculate full days and update remaining milliseconds
|
364
|
+
result.days = Math.floor(remainingMillis / ONE_DAY);
|
365
|
+
remainingMillis %= ONE_DAY; // Get the remainder milliseconds after taking out full days
|
366
|
+
// Calculate full hours from the remainder
|
367
|
+
result.hours = Math.floor(remainingMillis / ONE_HOUR);
|
368
|
+
remainingMillis %= ONE_HOUR; // Get the remainder milliseconds after taking out full hours
|
369
|
+
// Calculate full minutes from the remainder
|
370
|
+
result.minutes = Math.floor(remainingMillis / ONE_MINUTE);
|
371
|
+
remainingMillis %= ONE_MINUTE; // Get the remainder milliseconds after taking out full minutes
|
372
|
+
// Calculate full seconds from the remainder
|
373
|
+
result.seconds = Math.floor(remainingMillis / ONE_SECOND);
|
374
|
+
remainingMillis %= ONE_SECOND; // Get the remainder milliseconds after taking out full seconds
|
375
|
+
// The final remainder is the milliseconds component
|
376
|
+
result.miliseconds = remainingMillis;
|
377
|
+
// As noted above, setting month/year components to 0 as accurate
|
378
|
+
// calendar-aware calculation is not implemented here.
|
379
|
+
result.months = 0;
|
380
|
+
result.years = 0;
|
331
381
|
return result;
|
332
382
|
}
|
333
383
|
enumurate(unit = 'day', amount = 1) {
|
@@ -343,7 +393,7 @@ class AXDateTimeRange {
|
|
343
393
|
}
|
344
394
|
}
|
345
395
|
|
346
|
-
class
|
396
|
+
class AXGregorianCalendar extends AXCalendar {
|
347
397
|
/**
|
348
398
|
* @ignore
|
349
399
|
*/
|
@@ -354,7 +404,7 @@ class GeorgianCalendar extends AXCalendar {
|
|
354
404
|
return new AXDateTime(new Date(value.year, value.month - 1, value.date, value.hours || 0, value.minutes || 0, value.seconds || 0, value.ms || 0), this);
|
355
405
|
}
|
356
406
|
name() {
|
357
|
-
return '
|
407
|
+
return 'gregorian';
|
358
408
|
}
|
359
409
|
dayOfMonth(date) {
|
360
410
|
return date.getDate();
|
@@ -540,14 +590,14 @@ class GeorgianCalendar extends AXCalendar {
|
|
540
590
|
}
|
541
591
|
}
|
542
592
|
|
543
|
-
class
|
593
|
+
class AXSolarHijriCalendar extends AXCalendar {
|
544
594
|
/**
|
545
595
|
* @ignore
|
546
596
|
*/
|
547
597
|
constructor(config) {
|
548
598
|
super(config);
|
549
599
|
/*
|
550
|
-
|
600
|
+
SolarHijri years starting the 33-year rule.
|
551
601
|
*/
|
552
602
|
this.breaks = [-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210, 1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178];
|
553
603
|
}
|
@@ -556,13 +606,13 @@ class JalaliCalendar extends AXCalendar {
|
|
556
606
|
return new AXDateTime(new Date(a.getFullYear(), a.getMonth(), a.getDate(), value.hours || 0, value.minutes || 0, value.seconds || 0, value.ms || 0), this);
|
557
607
|
}
|
558
608
|
name() {
|
559
|
-
return '
|
609
|
+
return 'solar-hijri';
|
560
610
|
}
|
561
611
|
dayOfMonth(date) {
|
562
|
-
return this.
|
612
|
+
return this.toSolarHijri(date).day;
|
563
613
|
}
|
564
614
|
dayOfYear(date) {
|
565
|
-
const j = this.
|
615
|
+
const j = this.toSolarHijri(date);
|
566
616
|
return (j.month <= 6 ? (j.month - 1) * 31 : 6 * 31 + (j.month - 7) * 30) + j.day;
|
567
617
|
}
|
568
618
|
dayOfWeek(date) {
|
@@ -574,10 +624,10 @@ class JalaliCalendar extends AXCalendar {
|
|
574
624
|
return Math.ceil(((date.getTime() - firstDay.date.getTime()) / 86400000 + firstDay.date.getDay() + 1) / 7);
|
575
625
|
}
|
576
626
|
year(date) {
|
577
|
-
return this.
|
627
|
+
return this.toSolarHijri(date).year;
|
578
628
|
}
|
579
629
|
monthOfYear(date) {
|
580
|
-
return this.
|
630
|
+
return this.toSolarHijri(date).month;
|
581
631
|
}
|
582
632
|
add(date, unit, amount) {
|
583
633
|
let value = date.valueOf();
|
@@ -621,7 +671,7 @@ class JalaliCalendar extends AXCalendar {
|
|
621
671
|
const tempDate = this.toGregorian(jy, newMonth, 1);
|
622
672
|
const gregorianDate = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate());
|
623
673
|
// Adjust the day to either the original day or the last day of the new month, whichever is smaller
|
624
|
-
const lastDayOfNewMonth = this.
|
674
|
+
const lastDayOfNewMonth = this.SolarHijriMonthLength(jy, newMonth); // Implement this method to find the last day in a Jalali month
|
625
675
|
jd = Math.min(jd, lastDayOfNewMonth);
|
626
676
|
const finalDate = this.toGregorian(jy, newMonth, jd);
|
627
677
|
gregorianDate.setFullYear(finalDate.getFullYear());
|
@@ -653,7 +703,7 @@ class JalaliCalendar extends AXCalendar {
|
|
653
703
|
}
|
654
704
|
set(date, unit, value) {
|
655
705
|
const clone = new Date(date.valueOf());
|
656
|
-
const jDate = this.
|
706
|
+
const jDate = this.toSolarHijri(clone);
|
657
707
|
switch (unit) {
|
658
708
|
case 'second':
|
659
709
|
clone.setHours(clone.getHours(), clone.getMinutes(), value, clone.getMilliseconds());
|
@@ -738,13 +788,13 @@ class JalaliCalendar extends AXCalendar {
|
|
738
788
|
case 'month': {
|
739
789
|
const jy = this.year(date);
|
740
790
|
const jm = this.monthOfYear(date);
|
741
|
-
const jd = this.
|
791
|
+
const jd = this.SolarHijriMonthLength(jy, jm);
|
742
792
|
const gDate = this.toGregorian(jy, jm, jd);
|
743
793
|
return new AXDateTime(gDate, this).endOf('day');
|
744
794
|
}
|
745
795
|
case 'year': {
|
746
796
|
const jy = this.year(date);
|
747
|
-
const gDate = this.toGregorian(jy, 12, this.
|
797
|
+
const gDate = this.toGregorian(jy, 12, this.SolarHijriMonthLength(jy, 12));
|
748
798
|
return new AXDateTime(gDate, this).endOf('day');
|
749
799
|
}
|
750
800
|
}
|
@@ -763,9 +813,9 @@ class JalaliCalendar extends AXCalendar {
|
|
763
813
|
return new AXDateTime(date, this);
|
764
814
|
}
|
765
815
|
/*
|
766
|
-
Converts a Gregorian date to
|
816
|
+
Converts a Gregorian date to SolarHijri.
|
767
817
|
*/
|
768
|
-
|
818
|
+
toSolarHijri(date) {
|
769
819
|
const gd = date.getDate();
|
770
820
|
const gm = date.getMonth() + 1;
|
771
821
|
const gy = date.getFullYear();
|
@@ -777,47 +827,47 @@ class JalaliCalendar extends AXCalendar {
|
|
777
827
|
};
|
778
828
|
}
|
779
829
|
/*
|
780
|
-
Converts a
|
830
|
+
Converts a SolarHijri date to Gregorian.
|
781
831
|
*/
|
782
832
|
toGregorian(jy, jm, jd) {
|
783
833
|
const g = this.d2g(this.j2d(jy, jm, jd));
|
784
834
|
return new Date(g.gy, g.gm - 1, g.gd);
|
785
835
|
}
|
786
836
|
/*
|
787
|
-
Checks whether a
|
837
|
+
Checks whether a SolarHijri date is valid or not.
|
788
838
|
*/
|
789
|
-
|
790
|
-
return jy >= -61 && jy <= 3177 && jm >= 1 && jm <= 12 && jd >= 1 && jd <= this.
|
839
|
+
isValidSolarHijriDate(jy, jm, jd) {
|
840
|
+
return jy >= -61 && jy <= 3177 && jm >= 1 && jm <= 12 && jd >= 1 && jd <= this.SolarHijriMonthLength(jy, jm);
|
791
841
|
}
|
792
842
|
/*
|
793
843
|
Is this a leap year or not?
|
794
844
|
*/
|
795
|
-
|
845
|
+
isLeapSolarHijriYear(jy) {
|
796
846
|
return this.jalCalLeap(jy) === 0;
|
797
847
|
}
|
798
848
|
/*
|
799
|
-
Number of days in a given month in a
|
849
|
+
Number of days in a given month in a SolarHijri year.
|
800
850
|
*/
|
801
|
-
|
851
|
+
SolarHijriMonthLength(jy, jm) {
|
802
852
|
if (jm <= 6)
|
803
853
|
return 31;
|
804
854
|
if (jm <= 11)
|
805
855
|
return 30;
|
806
|
-
if (this.
|
856
|
+
if (this.isLeapSolarHijriYear(jy))
|
807
857
|
return 30;
|
808
858
|
return 29;
|
809
859
|
}
|
810
860
|
/*
|
811
|
-
This determines if the
|
861
|
+
This determines if the SolarHijri (Persian) year is
|
812
862
|
leap (366-day long) or is the common year (365 days)
|
813
863
|
|
814
|
-
@param jy
|
864
|
+
@param jy SolarHijri calendar year (-61 to 3177)
|
815
865
|
@returns number of years since the last leap year (0 to 4)
|
816
866
|
*/
|
817
867
|
jalCalLeap(jy) {
|
818
868
|
let bl = this.breaks.length, jp = this.breaks[0], jm, jump, leap, n, i;
|
819
869
|
if (jy < jp || jy >= this.breaks[bl - 1])
|
820
|
-
throw new Error('Invalid
|
870
|
+
throw new Error('Invalid SolarHijri year ' + jy);
|
821
871
|
for (i = 1; i < bl; i += 1) {
|
822
872
|
jm = this.breaks[i];
|
823
873
|
jump = jm - jp;
|
@@ -837,8 +887,8 @@ class JalaliCalendar extends AXCalendar {
|
|
837
887
|
jalCal(jy, withoutLeap) {
|
838
888
|
let bl = this.breaks.length, gy = jy + 621, leapJ = -14, jp = this.breaks[0], jm, jump, leap, leapG, march, n, i;
|
839
889
|
if (jy < jp || jy >= this.breaks[bl - 1])
|
840
|
-
throw new Error('Invalid
|
841
|
-
// Find the limiting years for the
|
890
|
+
throw new Error('Invalid SolarHijri year ' + jy);
|
891
|
+
// Find the limiting years for the SolarHijri year jy.
|
842
892
|
for (i = 1; i < bl; i += 1) {
|
843
893
|
jm = this.breaks[i];
|
844
894
|
jump = jm - jp;
|
@@ -849,7 +899,7 @@ class JalaliCalendar extends AXCalendar {
|
|
849
899
|
}
|
850
900
|
n = jy - jp;
|
851
901
|
// Find the number of leap years from AD 621 to the beginning
|
852
|
-
// of the current
|
902
|
+
// of the current SolarHijri year in the Persian calendar.
|
853
903
|
leapJ = leapJ + this.div(n, 33) * 8 + this.div(this.mod(n, 33) + 3, 4);
|
854
904
|
if (this.mod(jump, 33) === 4 && jump - n === 4)
|
855
905
|
leapJ += 1;
|
@@ -899,7 +949,7 @@ class JalaliCalendar extends AXCalendar {
|
|
899
949
|
}
|
900
950
|
}
|
901
951
|
else {
|
902
|
-
// Previous
|
952
|
+
// Previous SolarHijri year.
|
903
953
|
jy -= 1;
|
904
954
|
k += 179;
|
905
955
|
if (r.leap === 1)
|
@@ -932,8 +982,8 @@ class JalaliCalendar extends AXCalendar {
|
|
932
982
|
gd: gd,
|
933
983
|
};
|
934
984
|
}
|
935
|
-
|
936
|
-
let dayOfWeek = this.
|
985
|
+
SolarHijriWeek(jy, jm, jd) {
|
986
|
+
let dayOfWeek = this.SolarHijriToDateObject(jy, jm, jd, 0, 0, 0, 0).getDay();
|
937
987
|
let startDayDifference = dayOfWeek == 6 ? 0 : -(dayOfWeek + 1);
|
938
988
|
let endDayDifference = 6 + startDayDifference;
|
939
989
|
return {
|
@@ -941,7 +991,7 @@ class JalaliCalendar extends AXCalendar {
|
|
941
991
|
friday: this.d2j(this.j2d(jy, jm, jd + endDayDifference)),
|
942
992
|
};
|
943
993
|
}
|
944
|
-
|
994
|
+
SolarHijriToDateObject(jy, jm, jd, h = 0, m = 0, s = 0, ms = 0) {
|
945
995
|
let gregorianCalenderDate = this.toGregorian(jy, jm, jd);
|
946
996
|
return new Date(gregorianCalenderDate.getFullYear(), gregorianCalenderDate.getMonth() - 1, gregorianCalenderDate.getDate(), h || 0, m || 0, s || 0, ms || 0);
|
947
997
|
}
|
@@ -965,31 +1015,15 @@ const AX_DATETIME_CONFIG = new InjectionToken('AX_DATETIME_CONFIG', {
|
|
965
1015
|
},
|
966
1016
|
});
|
967
1017
|
const AXDateTimeDefaultConfig = {
|
968
|
-
calendar: '
|
1018
|
+
calendar: 'gregorian',
|
969
1019
|
calendars: {
|
970
|
-
|
1020
|
+
gregorian: new AXGregorianCalendar({
|
971
1021
|
weekdays: [0, 1, 2, 3, 4, 5, 6],
|
972
|
-
weekend: [5, 6]
|
973
|
-
formats: {
|
974
|
-
dateInput: 'yyyy/MM/dd',
|
975
|
-
timeInput: 'HH:mm',
|
976
|
-
dateTimeInput: 'yyyy/MM/dd HH:mm',
|
977
|
-
dateDisplay: 'DDDD, d MMM yyyy',
|
978
|
-
timeDisplay: 'HH:mm',
|
979
|
-
dateTimeDisplay: 'DDDD, d MMM yyyy HH:mm',
|
980
|
-
},
|
1022
|
+
weekend: [5, 6]
|
981
1023
|
}),
|
982
|
-
|
1024
|
+
"solar-hijri": new AXSolarHijriCalendar({
|
983
1025
|
weekdays: [6, 0, 1, 2, 3, 4, 5],
|
984
1026
|
weekend: [6],
|
985
|
-
formats: {
|
986
|
-
dateInput: 'yyyy/MM/dd',
|
987
|
-
timeInput: 'HH:mm',
|
988
|
-
dateTimeInput: 'yyyy/MM/dd HH:mm',
|
989
|
-
dateDisplay: 'DDDD, d MMM yyyy',
|
990
|
-
timeDisplay: 'HH:mm',
|
991
|
-
dateTimeDisplay: 'DDDD, d MMM yyyy HH:mm',
|
992
|
-
},
|
993
1027
|
}),
|
994
1028
|
},
|
995
1029
|
};
|
@@ -1028,7 +1062,7 @@ class AXCalendarService {
|
|
1028
1062
|
const calendar = this.resolveCalendar(name);
|
1029
1063
|
this.activeCalendar.next(calendar);
|
1030
1064
|
this.eventService.emitEvent({
|
1031
|
-
type:
|
1065
|
+
type: AXLocaleEvents.AXCalendarChanged,
|
1032
1066
|
payload: this.getActiveCalendar(),
|
1033
1067
|
});
|
1034
1068
|
}
|
@@ -1040,11 +1074,19 @@ class AXCalendarService {
|
|
1040
1074
|
this.config = inject(AX_DATETIME_CONFIG);
|
1041
1075
|
this._holidaysLoader = inject(AX_DATETIME_HOLIDAYS_LOADER);
|
1042
1076
|
this.eventService = inject(AXEventService);
|
1077
|
+
this.formatService = inject(AXFormatService);
|
1078
|
+
this.localeService = inject(AXLocaleService);
|
1043
1079
|
this.activeCalendar = new BehaviorSubject(this.getDefaultCalendar());
|
1044
1080
|
this.calendarChanges$ = this.activeCalendar.asObservable();
|
1045
1081
|
this.onHolidaysChanged = new Subject();
|
1046
1082
|
this._holidays = [];
|
1047
1083
|
this.loadHolidays();
|
1084
|
+
//
|
1085
|
+
this.localeService.profileChanged$.subscribe((locale) => {
|
1086
|
+
if (locale?.calendar?.system) {
|
1087
|
+
this.setActiveCalendar(locale.calendar.system);
|
1088
|
+
}
|
1089
|
+
});
|
1048
1090
|
}
|
1049
1091
|
loadHolidays(options) {
|
1050
1092
|
return this._holidaysLoader.getHolidays(options).then((value) => {
|
@@ -1052,11 +1094,15 @@ class AXCalendarService {
|
|
1052
1094
|
this.onHolidaysChanged.next(this._holidays);
|
1053
1095
|
});
|
1054
1096
|
}
|
1055
|
-
|
1097
|
+
isValidDate(value) {
|
1056
1098
|
try {
|
1057
1099
|
if (!value) {
|
1058
1100
|
return false;
|
1059
1101
|
}
|
1102
|
+
//
|
1103
|
+
if (value instanceof AXDateTime) {
|
1104
|
+
return true;
|
1105
|
+
}
|
1060
1106
|
// Check if it's a Date object
|
1061
1107
|
if (value instanceof Date) {
|
1062
1108
|
return !isNaN(value.getTime());
|
@@ -1083,10 +1129,13 @@ class AXCalendarService {
|
|
1083
1129
|
create(value, calendarName) {
|
1084
1130
|
try {
|
1085
1131
|
const calendar = calendarName ? this.resolveCalendar(calendarName) : this.calendar;
|
1086
|
-
if (!this.
|
1132
|
+
if (!this.isValidDate(value)) {
|
1087
1133
|
throw new Error(`Invalid Date value: ${value}`);
|
1088
1134
|
}
|
1089
|
-
if (
|
1135
|
+
if (value instanceof AXDateTime) {
|
1136
|
+
return value;
|
1137
|
+
}
|
1138
|
+
else if (typeof value === 'string') {
|
1090
1139
|
return new AXDateTime(new Date(value), calendar);
|
1091
1140
|
}
|
1092
1141
|
else if (value instanceof Date) {
|
@@ -1131,6 +1180,13 @@ class AXCalendarService {
|
|
1131
1180
|
const date = value instanceof AXDateTime ? value.date : value;
|
1132
1181
|
return new AXDateTime(date, calendar);
|
1133
1182
|
}
|
1183
|
+
format(value, format, options) {
|
1184
|
+
const calendar = options?.calendar ? this.resolveCalendar(options.calendar) : this.calendar;
|
1185
|
+
return this.formatService.format(value, 'datetime', {
|
1186
|
+
format: format,
|
1187
|
+
calendar: calendar.name(),
|
1188
|
+
});
|
1189
|
+
}
|
1134
1190
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXCalendarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
1135
1191
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXCalendarService, providedIn: 'root' }); }
|
1136
1192
|
}
|
@@ -1145,6 +1201,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
1145
1201
|
class AXDateTimePipe {
|
1146
1202
|
constructor() {
|
1147
1203
|
this._calendarService = inject(AXCalendarService);
|
1204
|
+
this.formatService = inject(AXFormatService);
|
1148
1205
|
}
|
1149
1206
|
transform(value, format, calendarName) {
|
1150
1207
|
if (value == null) {
|
@@ -1155,7 +1212,7 @@ class AXDateTimePipe {
|
|
1155
1212
|
calendar = this._calendarService.resolveCalendar(calendarName);
|
1156
1213
|
}
|
1157
1214
|
const val = this._calendarService.convert(value, calendar.name());
|
1158
|
-
return
|
1215
|
+
return this.formatService.format(val, 'datetime', format);
|
1159
1216
|
}
|
1160
1217
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateTimePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
1161
1218
|
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.5", ngImport: i0, type: AXDateTimePipe, isStandalone: true, name: "axDate" }); }
|
@@ -1167,12 +1224,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
1167
1224
|
|
1168
1225
|
class AXDateTimeFormatter {
|
1169
1226
|
constructor() {
|
1227
|
+
this.localeService = inject(AXLocaleService);
|
1170
1228
|
this.calendarService = inject(AXCalendarService);
|
1171
1229
|
}
|
1172
1230
|
get name() {
|
1173
1231
|
return 'datetime';
|
1174
1232
|
}
|
1175
1233
|
format(value, options) {
|
1234
|
+
if (isNil(value)) {
|
1235
|
+
return '';
|
1236
|
+
}
|
1237
|
+
//
|
1238
|
+
if (!this.calendarService.isValidDate(value))
|
1239
|
+
return 'Invalid date';
|
1240
|
+
//
|
1176
1241
|
const effectiveOptions = typeof options == 'object'
|
1177
1242
|
? {
|
1178
1243
|
format: options.format ?? 'date',
|
@@ -1183,15 +1248,29 @@ class AXDateTimeFormatter {
|
|
1183
1248
|
format: options,
|
1184
1249
|
calendar: this.calendarService.calendar.name(),
|
1185
1250
|
};
|
1186
|
-
const date = (value instanceof Date) ? value :
|
1187
|
-
(typeof value == "number" || typeof value == "string" ? new Date(value) : null);
|
1188
1251
|
//
|
1189
|
-
|
1190
|
-
|
1252
|
+
const formats = this.localeService.activeProfile().formats;
|
1253
|
+
const map = {
|
1254
|
+
longDate: formats.date.long,
|
1255
|
+
shortDate: formats.date.short,
|
1256
|
+
mediumDate: formats.date.medium,
|
1257
|
+
date: formats.date.short,
|
1258
|
+
//
|
1259
|
+
longTime: formats.time.long,
|
1260
|
+
shortTime: formats.time.short,
|
1261
|
+
mediumTime: formats.time.medium,
|
1262
|
+
time: formats.time.short,
|
1263
|
+
//
|
1264
|
+
long: formats.datetime.long,
|
1265
|
+
short: formats.datetime.short,
|
1266
|
+
medium: formats.datetime.medium,
|
1267
|
+
full: formats.datetime.full,
|
1268
|
+
};
|
1269
|
+
const format = map[effectiveOptions.format] ?? effectiveOptions.format ?? map['date'];
|
1191
1270
|
//
|
1192
1271
|
return this.calendarService
|
1193
|
-
.
|
1194
|
-
.format(
|
1272
|
+
.convert(value, effectiveOptions.calendar)
|
1273
|
+
.format(format, { locale: effectiveOptions.locale });
|
1195
1274
|
}
|
1196
1275
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateTimeFormatter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
1197
1276
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateTimeFormatter }); }
|
@@ -1337,11 +1416,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
1337
1416
|
type: Injectable
|
1338
1417
|
}] });
|
1339
1418
|
|
1419
|
+
class AXDateFormatter {
|
1420
|
+
constructor() {
|
1421
|
+
this.calendarService = inject(AXCalendarService);
|
1422
|
+
this.localeService = inject(AXLocaleService);
|
1423
|
+
}
|
1424
|
+
get name() {
|
1425
|
+
return 'date';
|
1426
|
+
}
|
1427
|
+
format(value, options) {
|
1428
|
+
if (isNil(value)) {
|
1429
|
+
return "";
|
1430
|
+
}
|
1431
|
+
//
|
1432
|
+
if (!this.calendarService.isValidDate(value))
|
1433
|
+
return "Invalid date";
|
1434
|
+
//
|
1435
|
+
const effectiveOptions = typeof options == 'object'
|
1436
|
+
? {
|
1437
|
+
format: options.format ?? 'short',
|
1438
|
+
locale: options.locale,
|
1439
|
+
calendar: options.calendar ?? this.calendarService.calendar.name(),
|
1440
|
+
}
|
1441
|
+
: {
|
1442
|
+
format: options,
|
1443
|
+
calendar: this.calendarService.calendar.name(),
|
1444
|
+
};
|
1445
|
+
//
|
1446
|
+
const formats = this.localeService.activeProfile().formats;
|
1447
|
+
const map = {
|
1448
|
+
"short": formats.date.short,
|
1449
|
+
"medium": formats.date.medium,
|
1450
|
+
"long": formats.date.long,
|
1451
|
+
"full": formats.date.full,
|
1452
|
+
};
|
1453
|
+
const format = map[effectiveOptions.format] ?? effectiveOptions.format ?? map['short'];
|
1454
|
+
//
|
1455
|
+
return this.calendarService
|
1456
|
+
.convert(value, effectiveOptions.calendar)
|
1457
|
+
.format(format, { locale: effectiveOptions.locale });
|
1458
|
+
}
|
1459
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateFormatter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
1460
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateFormatter }); }
|
1461
|
+
}
|
1462
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateFormatter, decorators: [{
|
1463
|
+
type: Injectable
|
1464
|
+
}] });
|
1465
|
+
|
1466
|
+
class AXTimeFormatter {
|
1467
|
+
constructor() {
|
1468
|
+
this.calendarService = inject(AXCalendarService);
|
1469
|
+
this.localeService = inject(AXLocaleService);
|
1470
|
+
}
|
1471
|
+
get name() {
|
1472
|
+
return 'time';
|
1473
|
+
}
|
1474
|
+
format(value, options) {
|
1475
|
+
if (isNil(value)) {
|
1476
|
+
return '';
|
1477
|
+
}
|
1478
|
+
//
|
1479
|
+
if (!this.calendarService.isValidDate(value))
|
1480
|
+
return 'Invalid date';
|
1481
|
+
//
|
1482
|
+
const effectiveOptions = typeof options == 'object'
|
1483
|
+
? {
|
1484
|
+
format: options.format ?? 'short',
|
1485
|
+
locale: options.locale,
|
1486
|
+
calendar: options.calendar ?? this.calendarService.calendar.name(),
|
1487
|
+
}
|
1488
|
+
: {
|
1489
|
+
format: options,
|
1490
|
+
calendar: this.calendarService.calendar.name(),
|
1491
|
+
};
|
1492
|
+
//
|
1493
|
+
const formats = this.localeService.activeProfile().formats;
|
1494
|
+
const map = {
|
1495
|
+
short: formats.time.short,
|
1496
|
+
medium: formats.time.medium,
|
1497
|
+
long: formats.time.long,
|
1498
|
+
full: formats.time.full,
|
1499
|
+
};
|
1500
|
+
const format = map[effectiveOptions.format] ?? effectiveOptions.format ?? map['short'];
|
1501
|
+
//
|
1502
|
+
return this.calendarService
|
1503
|
+
.convert(value, effectiveOptions.calendar)
|
1504
|
+
.format(format, { locale: effectiveOptions.locale });
|
1505
|
+
}
|
1506
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXTimeFormatter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
1507
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXTimeFormatter }); }
|
1508
|
+
}
|
1509
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXTimeFormatter, decorators: [{
|
1510
|
+
type: Injectable
|
1511
|
+
}] });
|
1512
|
+
|
1340
1513
|
class AXDateTimeModule {
|
1341
1514
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateTimeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
1342
1515
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.5", ngImport: i0, type: AXDateTimeModule, imports: [i1.AXFormatModule, AXDateTimePipe], exports: [AXDateTimePipe] }); }
|
1343
1516
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateTimeModule, imports: [AXFormatModule.forChild({
|
1344
|
-
formatters: [AXDateTimeFormatter, AXTimeLeftFormatter, AXTimeDurationFormatter],
|
1517
|
+
formatters: [AXDateTimeFormatter, AXDateFormatter, AXTimeFormatter, AXTimeLeftFormatter, AXTimeDurationFormatter],
|
1345
1518
|
})] }); }
|
1346
1519
|
}
|
1347
1520
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AXDateTimeModule, decorators: [{
|
@@ -1349,7 +1522,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
1349
1522
|
args: [{
|
1350
1523
|
imports: [
|
1351
1524
|
AXFormatModule.forChild({
|
1352
|
-
formatters: [AXDateTimeFormatter, AXTimeLeftFormatter, AXTimeDurationFormatter],
|
1525
|
+
formatters: [AXDateTimeFormatter, AXDateFormatter, AXTimeFormatter, AXTimeLeftFormatter, AXTimeDurationFormatter],
|
1353
1526
|
}),
|
1354
1527
|
AXDateTimePipe,
|
1355
1528
|
],
|
@@ -1361,5 +1534,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImpor
|
|
1361
1534
|
* Generated bundle index. Do not edit.
|
1362
1535
|
*/
|
1363
1536
|
|
1364
|
-
export { AXCalendar, AXCalendarMonth, AXCalendarService, AXDateTime, AXDateTimeDefaultConfig, AXDateTimeFormatter, AXDateTimeModule, AXDateTimePipe, AXDateTimeRange, AXHolidaysLoaderDefault, AXTimeLeftFormatter, AX_DATETIME_CONFIG, AX_DATETIME_HOLIDAYS_LOADER,
|
1537
|
+
export { AXCalendar, AXCalendarMonth, AXCalendarService, AXDateTime, AXDateTimeDefaultConfig, AXDateTimeFormatter, AXDateTimeModule, AXDateTimePipe, AXDateTimeRange, AXGregorianCalendar, AXHolidaysLoaderDefault, AXSolarHijriCalendar, AXTimeLeftFormatter, AX_DATETIME_CONFIG, AX_DATETIME_HOLIDAYS_LOADER, dateTimeConfig };
|
1365
1538
|
//# sourceMappingURL=acorex-core-date-time.mjs.map
|