@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.
Files changed (47) hide show
  1. package/date-time/index.d.ts +5 -5
  2. package/date-time/lib/calendar.service.d.ts +8 -3
  3. package/date-time/lib/dateTime.config.d.ts +1 -1
  4. package/date-time/lib/datetime.pipe.d.ts +2 -1
  5. package/date-time/lib/{datetime.class.d.ts → datetime.types.d.ts} +2 -2
  6. package/date-time/lib/formatters/date.formatter.d.ts +12 -0
  7. package/date-time/lib/formatters/{datetime-formatter.d.ts → datetime.formatter.d.ts} +3 -1
  8. package/date-time/lib/formatters/time.formatter.d.ts +12 -0
  9. package/date-time/lib/{georgian.calendar.d.ts → gregorian.calendar.d.ts} +2 -2
  10. package/date-time/lib/{jalali.calendar.d.ts → solar-hijri.calendar.d.ts} +8 -8
  11. package/events/index.d.ts +0 -1
  12. package/fesm2022/acorex-core-date-time.mjs +305 -132
  13. package/fesm2022/acorex-core-date-time.mjs.map +1 -1
  14. package/fesm2022/acorex-core-events.mjs +1 -7
  15. package/fesm2022/acorex-core-events.mjs.map +1 -1
  16. package/fesm2022/acorex-core-format.mjs +47 -33
  17. package/fesm2022/acorex-core-format.mjs.map +1 -1
  18. package/fesm2022/acorex-core-locale-en-AU.profile-BW-_9tgT.mjs +64 -0
  19. package/fesm2022/acorex-core-locale-en-AU.profile-BW-_9tgT.mjs.map +1 -0
  20. package/fesm2022/acorex-core-locale.mjs +341 -0
  21. package/fesm2022/acorex-core-locale.mjs.map +1 -0
  22. package/fesm2022/acorex-core-translation.mjs +12 -4
  23. package/fesm2022/acorex-core-translation.mjs.map +1 -1
  24. package/format/index.d.ts +2 -2
  25. package/format/lib/format.directive.d.ts +1 -1
  26. package/format/lib/format.module.d.ts +3 -3
  27. package/locale/README.md +3 -0
  28. package/locale/index.d.ts +8 -0
  29. package/locale/lib/formatters/currency.formatter.d.ts +10 -0
  30. package/locale/lib/locale-profile-provider.service.d.ts +24 -0
  31. package/locale/lib/locale.config.d.ts +5 -0
  32. package/locale/lib/locale.module.d.ts +7 -0
  33. package/locale/lib/locale.service.d.ts +20 -0
  34. package/locale/lib/locale.types.d.ts +61 -0
  35. package/locale/lib/profiles/en-AU.profile.d.ts +2 -0
  36. package/locale/lib/profiles/en-US.profile.d.ts +2 -0
  37. package/locale/lib/profiles/fa-IR.profile.d.ts +2 -0
  38. package/package.json +5 -1
  39. package/translation/lib/translation.service.d.ts +1 -0
  40. package/types/README.md +2 -2
  41. package/events/lib/event.type.d.ts +0 -5
  42. package/i18n/en/common.json +0 -191
  43. package/i18n/fa/common.json +0 -190
  44. /package/date-time/lib/formatters/{time-duration-formatter.d.ts → time-duration.formatter.d.ts} +0 -0
  45. /package/date-time/lib/formatters/{timeleft-formatter.d.ts → timeleft.formatter.d.ts} +0 -0
  46. /package/format/lib/formatters/{number-formatter.d.ts → number.formatter.d.ts} +0 -0
  47. /package/format/lib/formatters/{string-formatter.d.ts → string.formatter.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import { AXEventTypes, AXEventService } from '@acorex/core/events';
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
- return this._config.formats;
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
- ss: () => this.pad(this.date.getSeconds(), 2),
40
+ // 0 1 ... 58 59
40
41
  s: () => this.date.getSeconds().toString(),
41
- //
42
- dd: () => this.pad(this.calendar.dayOfMonth(this.date), 2),
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
- d: () => this.calendar.dayOfMonth(this.date).toString(),
45
- //
46
- mm: () => this.pad(this.date.getMinutes(), 2),
47
- m: () => this.date.getMinutes().toString(),
48
- //
49
- MMMM: () => translateSync(`dateTime.months.${this.calendar.name()}.long.${this.calendar.monthOfYear(this.date) - 1}`),
50
- MMM: () => translateSync(`dateTime.months.${this.calendar.name()}.short.${this.calendar.monthOfYear(this.date) - 1}`),
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
- M: () => this.calendar.monthOfYear(this.date),
53
- //
54
- E: () => translateSync(`dateTime.weekdays.long.${this.calendar.weekdays[this.calendar.dayOfWeek(this.date) - 1]}`),
55
- DDD: () => translateSync(`dateTime.weekdays.short.${this.calendar.weekdays[this.calendar.dayOfWeek(this.date) - 1]}`),
56
- DDDD: () => this._formatKeys['E'](),
57
- //
58
- yyyy: () => this.pad(this.calendar.year(this.date), 4),
59
- YYYY: () => this.pad(this.calendar.year(this.date), 4),
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
- HH: () => this.pad(this.date.getHours(), 2),
64
- H: () => this.date.getHours().toString(),
65
- //
66
- hh: () => this.pad(this.date.getHours() % 12 || 12, 2),
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-GB');
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
- const r = f(effectiveOptions);
144
- return r;
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
- const one_second = 1000;
296
- const one_min = one_second * 60;
297
- const one_hour = one_min * 60;
298
- const one_day = one_hour * 24;
299
- const one_week = one_day * 7;
300
- const one_year = 365.25 * one_day;
301
- const one_month = one_year / 12;
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 = Number((diff / one_second).toFixed(2));
308
- result.total.minutes = Number((diff / one_min).toFixed(2));
309
- result.total.hours = Number((diff / one_hour).toFixed(2));
310
- result.total.days = Number((diff / one_day).toFixed(2));
311
- result.total.weeks = Number((diff / one_week).toFixed(2));
312
- //
313
- // let months = (this.endTime.year - this.startTime.year) * 12;
314
- // months += this.endTime.monthOfYear - this.startTime.monthOfYear + 1;
315
- // if (this.endTime.dayOfYear < this.startTime.dayOfYear) {
316
- // months--;
317
- // }
318
- // result.total.months = Math.abs(months);
319
- // TODO: review
320
- result.total.months = Number((diff / one_month).toFixed(2));
321
- result.total.years = Number((diff / one_year).toFixed(2));
322
- //
323
- result.miliseconds = result.total.miliseconds % 1000;
324
- result.seconds = Number((result.total.seconds % 60).toFixed(0));
325
- result.minutes = Number((result.total.minutes % 60).toFixed(0));
326
- result.hours = Number((result.total.hours % 24).toFixed(0));
327
- // TODO: review
328
- result.days = Number((result.total.days % 30.4).toFixed(0));
329
- result.months = Number((result.total.months % 12).toFixed(0));
330
- result.years = Number(result.total.years.toFixed(0));
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 GeorgianCalendar extends AXCalendar {
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 'georgian';
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 JalaliCalendar extends AXCalendar {
593
+ class AXSolarHijriCalendar extends AXCalendar {
544
594
  /**
545
595
  * @ignore
546
596
  */
547
597
  constructor(config) {
548
598
  super(config);
549
599
  /*
550
- Jalaali years starting the 33-year rule.
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 'jalali';
609
+ return 'solar-hijri';
560
610
  }
561
611
  dayOfMonth(date) {
562
- return this.toJalaali(date).day;
612
+ return this.toSolarHijri(date).day;
563
613
  }
564
614
  dayOfYear(date) {
565
- const j = this.toJalaali(date);
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.toJalaali(date).year;
627
+ return this.toSolarHijri(date).year;
578
628
  }
579
629
  monthOfYear(date) {
580
- return this.toJalaali(date).month;
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.jalaaliMonthLength(jy, newMonth); // Implement this method to find the last day in a Jalali month
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.toJalaali(clone);
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.jalaaliMonthLength(jy, jm);
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.jalaaliMonthLength(jy, 12));
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 Jalaali.
816
+ Converts a Gregorian date to SolarHijri.
767
817
  */
768
- toJalaali(date) {
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 Jalaali date to Gregorian.
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 Jalaali date is valid or not.
837
+ Checks whether a SolarHijri date is valid or not.
788
838
  */
789
- isValidJalaaliDate(jy, jm, jd) {
790
- return jy >= -61 && jy <= 3177 && jm >= 1 && jm <= 12 && jd >= 1 && jd <= this.jalaaliMonthLength(jy, jm);
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
- isLeapJalaaliYear(jy) {
845
+ isLeapSolarHijriYear(jy) {
796
846
  return this.jalCalLeap(jy) === 0;
797
847
  }
798
848
  /*
799
- Number of days in a given month in a Jalaali year.
849
+ Number of days in a given month in a SolarHijri year.
800
850
  */
801
- jalaaliMonthLength(jy, jm) {
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.isLeapJalaaliYear(jy))
856
+ if (this.isLeapSolarHijriYear(jy))
807
857
  return 30;
808
858
  return 29;
809
859
  }
810
860
  /*
811
- This determines if the Jalaali (Persian) year is
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 Jalaali calendar year (-61 to 3177)
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 Jalaali year ' + jy);
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 Jalaali year ' + jy);
841
- // Find the limiting years for the Jalaali year jy.
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 Jalaali year in the Persian calendar.
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 Jalaali year.
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
- jalaaliWeek(jy, jm, jd) {
936
- let dayOfWeek = this.jalaaliToDateObject(jy, jm, jd, 0, 0, 0, 0).getDay();
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
- jalaaliToDateObject(jy, jm, jd, h = 0, m = 0, s = 0, ms = 0) {
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: 'georgian',
1018
+ calendar: 'gregorian',
969
1019
  calendars: {
970
- georgian: new GeorgianCalendar({
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
- jalali: new JalaliCalendar({
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: AXEventTypes.AXCalendarChanged,
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
- isDate(value) {
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.isDate(value)) {
1132
+ if (!this.isValidDate(value)) {
1087
1133
  throw new Error(`Invalid Date value: ${value}`);
1088
1134
  }
1089
- if (typeof value === 'string') {
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 val.format(format);
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
- if (!date)
1190
- return "";
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
- .create(date, effectiveOptions.calendar)
1194
- .format(effectiveOptions.format, { locale: effectiveOptions.locale });
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, GeorgianCalendar, JalaliCalendar, dateTimeConfig };
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