@acorex/core 16.0.2 → 17.0.1
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/common/README.md +3 -0
- package/common/countries/countries.data.d.ts +2 -0
- package/common/countries/country.d.ts +13 -0
- package/common/index.d.ts +2 -0
- package/config/README.md +3 -0
- package/config/index.d.ts +2 -0
- package/config/lib/configs.d.ts +6 -0
- package/config/lib/configs.service.d.ts +12 -0
- package/date-time/README.md +3 -0
- package/date-time/index.d.ts +10 -0
- package/date-time/lib/calendar.service.d.ts +27 -0
- package/date-time/lib/dateTime.config.d.ts +12 -0
- package/date-time/lib/datetime.class.d.ts +138 -0
- package/date-time/lib/datetime.module.d.ts +8 -0
- package/date-time/lib/datetime.pipe.d.ts +12 -0
- package/date-time/lib/formatters/datetime-formatter.d.ts +19 -0
- package/date-time/lib/formatters/timeleft-formatter.d.ts +16 -0
- package/date-time/lib/georgian.calendar.d.ts +21 -0
- package/date-time/lib/holidays.loader.d.ts +21 -0
- package/date-time/lib/jalali.calendar.d.ts +40 -0
- package/esm2022/common/acorex-core-common.mjs +5 -0
- package/esm2022/common/countries/countries.data.mjs +2625 -0
- package/esm2022/common/countries/country.mjs +2 -0
- package/esm2022/common/index.mjs +3 -0
- package/esm2022/config/acorex-core-config.mjs +5 -0
- package/esm2022/config/index.mjs +3 -0
- package/esm2022/config/lib/configs.mjs +7 -0
- package/esm2022/config/lib/configs.service.mjs +27 -0
- package/esm2022/date-time/acorex-core-date-time.mjs +5 -0
- package/esm2022/date-time/index.mjs +11 -0
- package/esm2022/date-time/lib/calendar.service.mjs +100 -0
- package/esm2022/date-time/lib/dateTime.config.mjs +50 -0
- package/esm2022/date-time/lib/datetime.class.mjs +337 -0
- package/esm2022/date-time/lib/datetime.module.mjs +27 -0
- package/esm2022/date-time/lib/datetime.pipe.mjs +29 -0
- package/esm2022/date-time/lib/formatters/datetime-formatter.mjs +32 -0
- package/esm2022/date-time/lib/formatters/timeleft-formatter.mjs +91 -0
- package/esm2022/date-time/lib/georgian.calendar.mjs +203 -0
- package/esm2022/date-time/lib/holidays.loader.mjs +13 -0
- package/esm2022/date-time/lib/jalali.calendar.mjs +440 -0
- package/esm2022/events/acorex-core-events.mjs +5 -0
- package/esm2022/events/index.mjs +3 -0
- package/esm2022/events/lib/event.service.mjs +43 -0
- package/esm2022/events/lib/event.type.mjs +6 -0
- package/esm2022/file/acorex-core-file.mjs +5 -0
- package/esm2022/file/index.mjs +7 -0
- package/esm2022/file/lib/file-download-ref.class.mjs +12 -0
- package/esm2022/file/lib/file-download-result.class.mjs +45 -0
- package/esm2022/file/lib/file-size-formatter.mjs +24 -0
- package/esm2022/file/lib/file-upload-ref.class.mjs +12 -0
- package/esm2022/file/lib/file.module.mjs +20 -0
- package/esm2022/file/lib/file.service.mjs +103 -0
- package/esm2022/format/acorex-core-format.mjs +5 -0
- package/esm2022/format/index.mjs +8 -0
- package/esm2022/format/lib/format.config.mjs +3 -0
- package/esm2022/format/lib/format.module.mjs +64 -0
- package/esm2022/format/lib/format.pipe.mjs +37 -0
- package/esm2022/format/lib/format.service.mjs +95 -0
- package/esm2022/format/lib/format.types.mjs +2 -0
- package/esm2022/format/lib/formatters/number-formatter.mjs +74 -0
- package/esm2022/format/lib/formatters/string-formatter.mjs +15 -0
- package/esm2022/image/acorex-core-image.mjs +5 -0
- package/esm2022/image/index.mjs +2 -0
- package/esm2022/image/lib/image.service.mjs +43 -0
- package/esm2022/index.mjs +2 -44
- package/esm2022/memorize/acorex-core-memorize.mjs +5 -0
- package/esm2022/memorize/index.mjs +2 -0
- package/esm2022/memorize/lib/memorize.decorator.mjs +19 -0
- package/esm2022/pipes/acorex-core-pipes.mjs +5 -0
- package/esm2022/pipes/index.mjs +2 -0
- package/esm2022/pipes/lib/safe/safe.pipe.mjs +38 -0
- package/esm2022/platform/acorex-core-platform.mjs +5 -0
- package/esm2022/platform/index.mjs +2 -0
- package/esm2022/platform/lib/platform.service.mjs +225 -0
- package/esm2022/storage/acorex-core-storage.mjs +5 -0
- package/esm2022/storage/cookie-storage.service.mjs +202 -0
- package/esm2022/storage/index.mjs +5 -0
- package/esm2022/storage/local-storage.service.mjs +58 -0
- package/esm2022/storage/session-storage.service.mjs +22 -0
- package/esm2022/storage/storage.interface.mjs +2 -0
- package/esm2022/translation/acorex-core-translation.mjs +5 -0
- package/esm2022/translation/index.mjs +9 -0
- package/esm2022/translation/lib/translation-scope.resolver.mjs +11 -0
- package/esm2022/translation/lib/translation.config.mjs +20 -0
- package/esm2022/translation/lib/translation.loader.mjs +14 -0
- package/esm2022/translation/lib/translation.module.mjs +40 -0
- package/esm2022/translation/lib/translation.service.mjs +173 -0
- package/esm2022/translation/lib/translation.types.mjs +2 -0
- package/esm2022/translation/lib/translator.directive.mjs +28 -0
- package/esm2022/translation/lib/translator.pipe.mjs +23 -0
- package/esm2022/types/acorex-core-types.mjs +5 -0
- package/esm2022/types/index.mjs +2 -0
- package/esm2022/utils/acorex-core-utils.mjs +5 -0
- package/esm2022/utils/index.mjs +6 -0
- package/esm2022/utils/lib/auto-unsubscribe.mjs +36 -0
- package/esm2022/utils/lib/color-util.mjs +111 -0
- package/esm2022/utils/lib/drawing-util.mjs +35 -0
- package/esm2022/utils/lib/html-util.mjs +39 -0
- package/esm2022/utils/lib/string-util.mjs +19 -0
- package/esm2022/validation/acorex-core-validation.mjs +5 -0
- package/esm2022/validation/index.mjs +18 -0
- package/esm2022/validation/lib/rules/between-rule.mjs +31 -0
- package/esm2022/validation/lib/rules/callback-rule.mjs +29 -0
- package/esm2022/validation/lib/rules/equal-rule.mjs +26 -0
- package/esm2022/validation/lib/rules/greater-than.mjs +29 -0
- package/esm2022/validation/lib/rules/length-rule.mjs +26 -0
- package/esm2022/validation/lib/rules/less-than-rule.mjs +29 -0
- package/esm2022/validation/lib/rules/maxlength-rule.mjs +27 -0
- package/esm2022/validation/lib/rules/minlength-rule.mjs +26 -0
- package/esm2022/validation/lib/rules/regex-rule.mjs +49 -0
- package/esm2022/validation/lib/rules/required-rule.mjs +36 -0
- package/esm2022/validation/lib/validation.config.mjs +33 -0
- package/esm2022/validation/lib/validation.module.mjs +84 -0
- package/esm2022/validation/lib/validation.service.mjs +98 -0
- package/esm2022/validation/lib/validation.types.mjs +3 -0
- package/events/README.md +3 -0
- package/events/index.d.ts +2 -0
- package/{lib/services → events/lib}/event.service.d.ts +8 -0
- package/events/lib/event.type.d.ts +5 -0
- package/fesm2022/acorex-core-common.mjs +2631 -0
- package/fesm2022/acorex-core-common.mjs.map +1 -0
- package/fesm2022/acorex-core-config.mjs +39 -0
- package/fesm2022/acorex-core-config.mjs.map +1 -0
- package/fesm2022/acorex-core-date-time.mjs +1305 -0
- package/fesm2022/acorex-core-date-time.mjs.map +1 -0
- package/fesm2022/acorex-core-events.mjs +56 -0
- package/fesm2022/acorex-core-events.mjs.map +1 -0
- package/fesm2022/acorex-core-file.mjs +214 -0
- package/fesm2022/acorex-core-file.mjs.map +1 -0
- package/fesm2022/acorex-core-format.mjs +282 -0
- package/fesm2022/acorex-core-format.mjs.map +1 -0
- package/fesm2022/acorex-core-image.mjs +50 -0
- package/fesm2022/acorex-core-image.mjs.map +1 -0
- package/fesm2022/acorex-core-memorize.mjs +26 -0
- package/fesm2022/acorex-core-memorize.mjs.map +1 -0
- package/fesm2022/acorex-core-pipes.mjs +44 -0
- package/fesm2022/acorex-core-pipes.mjs.map +1 -0
- package/fesm2022/acorex-core-platform.mjs +232 -0
- package/fesm2022/acorex-core-platform.mjs.map +1 -0
- package/fesm2022/acorex-core-storage.mjs +285 -0
- package/fesm2022/acorex-core-storage.mjs.map +1 -0
- package/fesm2022/acorex-core-translation.mjs +293 -0
- package/fesm2022/acorex-core-translation.mjs.map +1 -0
- package/fesm2022/acorex-core-types.mjs +6 -0
- package/fesm2022/acorex-core-types.mjs.map +1 -0
- package/fesm2022/acorex-core-utils.mjs +247 -0
- package/fesm2022/acorex-core-utils.mjs.map +1 -0
- package/fesm2022/acorex-core-validation.mjs +488 -0
- package/fesm2022/acorex-core-validation.mjs.map +1 -0
- package/fesm2022/acorex-core.mjs +2 -2309
- package/fesm2022/acorex-core.mjs.map +1 -1
- package/file/README.md +3 -0
- package/file/index.d.ts +6 -0
- package/file/lib/file-download-ref.class.d.ts +6 -0
- package/file/lib/file-download-result.class.d.ts +8 -0
- package/file/lib/file-size-formatter.d.ts +16 -0
- package/file/lib/file-upload-ref.class.d.ts +5 -0
- package/file/lib/file.module.d.ts +7 -0
- package/file/lib/file.service.d.ts +18 -0
- package/format/README.md +3 -0
- package/format/index.d.ts +7 -0
- package/format/lib/format.config.d.ts +5 -0
- package/format/lib/format.module.d.ts +18 -0
- package/format/lib/format.pipe.d.ts +12 -0
- package/format/lib/format.service.d.ts +43 -0
- package/format/lib/format.types.d.ts +4 -0
- package/format/lib/formatters/number-formatter.d.ts +23 -0
- package/format/lib/formatters/string-formatter.d.ts +14 -0
- package/image/README.md +3 -0
- package/image/index.d.ts +1 -0
- package/image/lib/image.service.d.ts +11 -0
- package/index.d.ts +1 -43
- package/memorize/README.md +3 -0
- package/memorize/index.d.ts +1 -0
- package/memorize/lib/memorize.decorator.d.ts +1 -0
- package/package.json +98 -5
- package/pipes/README.md +3 -0
- package/pipes/index.d.ts +1 -0
- package/pipes/lib/safe/safe.pipe.d.ts +10 -0
- package/platform/README.md +3 -0
- package/platform/index.d.ts +1 -0
- package/{lib/platform → platform/lib}/platform.service.d.ts +14 -6
- package/storage/README.md +3 -0
- package/storage/cookie-storage.service.d.ts +104 -0
- package/storage/index.d.ts +4 -0
- package/storage/local-storage.service.d.ts +16 -0
- package/storage/session-storage.service.d.ts +10 -0
- package/storage/storage.interface.d.ts +14 -0
- package/translation/README.md +3 -0
- package/translation/index.d.ts +8 -0
- package/translation/lib/translation-scope.resolver.d.ts +2 -0
- package/translation/lib/translation.config.d.ts +14 -0
- package/translation/lib/translation.loader.d.ts +14 -0
- package/translation/lib/translation.module.d.ts +8 -0
- package/translation/lib/translation.service.d.ts +31 -0
- package/translation/lib/translation.types.d.ts +10 -0
- package/translation/lib/translator.directive.d.ts +12 -0
- package/translation/lib/translator.pipe.d.ts +12 -0
- package/types/README.md +3 -0
- package/types/index.d.ts +2 -0
- package/utils/README.md +3 -0
- package/utils/index.d.ts +5 -0
- package/utils/lib/auto-unsubscribe.d.ts +12 -0
- package/utils/lib/color-util.d.ts +24 -0
- package/utils/lib/drawing-util.d.ts +18 -0
- package/utils/lib/html-util.d.ts +5 -0
- package/utils/lib/string-util.d.ts +6 -0
- package/validation/README.md +3 -0
- package/validation/index.d.ts +14 -0
- package/validation/lib/rules/between-rule.d.ts +18 -0
- package/validation/lib/rules/callback-rule.d.ts +23 -0
- package/validation/lib/rules/equal-rule.d.ts +17 -0
- package/validation/lib/rules/greater-than.d.ts +17 -0
- package/validation/lib/rules/length-rule.d.ts +17 -0
- package/validation/lib/rules/less-than-rule.d.ts +17 -0
- package/validation/lib/rules/maxlength-rule.d.ts +16 -0
- package/validation/lib/rules/minlength-rule.d.ts +16 -0
- package/validation/lib/rules/regex-rule.d.ts +17 -0
- package/validation/lib/rules/required-rule.d.ts +16 -0
- package/validation/lib/validation.config.d.ts +15 -0
- package/validation/lib/validation.module.d.ts +17 -0
- package/validation/lib/validation.service.d.ts +35 -0
- package/validation/lib/validation.types.d.ts +21 -0
- package/esm2022/lib/classes/base-page.class.mjs +0 -26
- package/esm2022/lib/classes/color.class.mjs +0 -49
- package/esm2022/lib/classes/datetime.class.mjs +0 -323
- package/esm2022/lib/classes/menu.class.mjs +0 -35
- package/esm2022/lib/classes/navigator.class.mjs +0 -2
- package/esm2022/lib/classes/popup.class.mjs +0 -2
- package/esm2022/lib/classes/promise.class.mjs +0 -21
- package/esm2022/lib/classes/sectionlist.class.mjs +0 -2
- package/esm2022/lib/classes/select.class.mjs +0 -8
- package/esm2022/lib/core.module.mjs +0 -27
- package/esm2022/lib/error/error.class.mjs +0 -2
- package/esm2022/lib/error/error.module.mjs +0 -19
- package/esm2022/lib/error/error.service.mjs +0 -22
- package/esm2022/lib/events/keyboard.mjs +0 -2
- package/esm2022/lib/http/http-error.class.mjs +0 -2
- package/esm2022/lib/http/http-events.interceptor.mjs +0 -3
- package/esm2022/lib/http/http-request.class.mjs +0 -2
- package/esm2022/lib/http/http-result.class.mjs +0 -25
- package/esm2022/lib/http/http.module.mjs +0 -35
- package/esm2022/lib/http/http.service.mjs +0 -148
- package/esm2022/lib/locale/en.json +0 -255
- package/esm2022/lib/locale/fa.json +0 -245
- package/esm2022/lib/pipe/datetime.pipe.mjs +0 -25
- package/esm2022/lib/pipe/htmlToText.pipe.mjs +0 -25
- package/esm2022/lib/platform/index.mjs +0 -2
- package/esm2022/lib/platform/platform.service.mjs +0 -152
- package/esm2022/lib/services/config.mjs +0 -29
- package/esm2022/lib/services/event.service.mjs +0 -34
- package/esm2022/lib/services/navigator.service.mjs +0 -10
- package/esm2022/lib/services/storage.service.mjs +0 -16
- package/esm2022/lib/translator/translator.mjs +0 -26
- package/esm2022/lib/translator/translator.module.mjs +0 -25
- package/esm2022/lib/translator/translator.pipe.mjs +0 -24
- package/esm2022/lib/translator/translator.service.mjs +0 -21
- package/esm2022/lib/utils/array/array-util.mjs +0 -133
- package/esm2022/lib/utils/html/html-util.mjs +0 -200
- package/esm2022/lib/utils/html/html.module.mjs +0 -19
- package/esm2022/lib/utils/math/math-util.mjs +0 -6
- package/esm2022/lib/utils/object/object-util.mjs +0 -83
- package/esm2022/lib/utils/render/on-demand-preload-strategy.service.mjs +0 -21
- package/esm2022/lib/utils/render/render.service.mjs +0 -109
- package/esm2022/lib/utils/render/rendering.module.mjs +0 -35
- package/esm2022/lib/utils/scroll/scroll.directive.mjs +0 -56
- package/esm2022/lib/utils/scroll/scroll.module.mjs +0 -19
- package/esm2022/lib/utils/separator/separator.module.mjs +0 -19
- package/esm2022/lib/utils/separator/separator.pipe.mjs +0 -33
- package/lib/classes/base-page.class.d.ts +0 -13
- package/lib/classes/color.class.d.ts +0 -17
- package/lib/classes/datetime.class.d.ts +0 -63
- package/lib/classes/menu.class.d.ts +0 -34
- package/lib/classes/navigator.class.d.ts +0 -5
- package/lib/classes/popup.class.d.ts +0 -12
- package/lib/classes/promise.class.d.ts +0 -7
- package/lib/classes/sectionlist.class.d.ts +0 -8
- package/lib/classes/select.class.d.ts +0 -7
- package/lib/core.module.d.ts +0 -9
- package/lib/error/error.class.d.ts +0 -4
- package/lib/error/error.module.d.ts +0 -7
- package/lib/error/error.service.d.ts +0 -13
- package/lib/events/keyboard.d.ts +0 -2
- package/lib/http/http-error.class.d.ts +0 -7
- package/lib/http/http-events.interceptor.d.ts +0 -10
- package/lib/http/http-request.class.d.ts +0 -14
- package/lib/http/http-result.class.d.ts +0 -11
- package/lib/http/http.module.d.ts +0 -10
- package/lib/http/http.service.d.ts +0 -23
- package/lib/pipe/datetime.pipe.d.ts +0 -8
- package/lib/pipe/htmlToText.pipe.d.ts +0 -7
- package/lib/platform/index.d.ts +0 -1
- package/lib/services/config.d.ts +0 -9
- package/lib/services/navigator.service.d.ts +0 -8
- package/lib/services/storage.service.d.ts +0 -7
- package/lib/translator/translator.d.ts +0 -9
- package/lib/translator/translator.module.d.ts +0 -8
- package/lib/translator/translator.pipe.d.ts +0 -8
- package/lib/translator/translator.service.d.ts +0 -8
- package/lib/utils/array/array-util.d.ts +0 -6
- package/lib/utils/html/html-util.d.ts +0 -62
- package/lib/utils/html/html.module.d.ts +0 -8
- package/lib/utils/math/math-util.d.ts +0 -3
- package/lib/utils/object/object-util.d.ts +0 -7
- package/lib/utils/render/on-demand-preload-strategy.service.d.ts +0 -10
- package/lib/utils/render/render.service.d.ts +0 -18
- package/lib/utils/render/rendering.module.d.ts +0 -8
- package/lib/utils/scroll/scroll.directive.d.ts +0 -18
- package/lib/utils/scroll/scroll.module.d.ts +0 -8
- package/lib/utils/separator/separator.module.d.ts +0 -8
- package/lib/utils/separator/separator.pipe.d.ts +0 -8
|
@@ -0,0 +1,1305 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, Injectable, Pipe, NgModule } from '@angular/core';
|
|
3
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
4
|
+
import { AX_GLOBAL_CONFIG } from '@acorex/core/config';
|
|
5
|
+
import { defaults, orderBy, set, isNil } from 'lodash-es';
|
|
6
|
+
import { isBrowser } from '@acorex/core/platform';
|
|
7
|
+
import { translateSync } from '@acorex/core/translation';
|
|
8
|
+
import { AXEventTypes, AXEventService } from '@acorex/core/events';
|
|
9
|
+
import * as i1 from '@acorex/core/format';
|
|
10
|
+
import { AXFormatModule } from '@acorex/core/format';
|
|
11
|
+
|
|
12
|
+
class AXCalendar {
|
|
13
|
+
/**
|
|
14
|
+
* @ignore
|
|
15
|
+
*/
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this._config = config;
|
|
18
|
+
}
|
|
19
|
+
get weekend() {
|
|
20
|
+
return this._config.weekend;
|
|
21
|
+
}
|
|
22
|
+
get formats() {
|
|
23
|
+
return this._config.formats;
|
|
24
|
+
}
|
|
25
|
+
get weekdays() {
|
|
26
|
+
return this._config.weekdays;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
class AXDateTime {
|
|
30
|
+
get date() {
|
|
31
|
+
return this._date;
|
|
32
|
+
}
|
|
33
|
+
get calendar() {
|
|
34
|
+
return this._calendar;
|
|
35
|
+
}
|
|
36
|
+
constructor(value, calendar) {
|
|
37
|
+
//TODO: remove unused items
|
|
38
|
+
this._formatKeys = {
|
|
39
|
+
ss: () => this.pad(this.date.getSeconds(), 2),
|
|
40
|
+
s: () => this.date.getSeconds().toString(),
|
|
41
|
+
//
|
|
42
|
+
dd: () => this.pad(this.calendar.dayOfMonth(this.date), 2),
|
|
43
|
+
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}`),
|
|
51
|
+
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),
|
|
60
|
+
yy: () => this.pad(this.calendar.year(this.date), 4).substring(2),
|
|
61
|
+
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),
|
|
67
|
+
h: () => (this.date.getHours() % 12 || 12).toString(),
|
|
68
|
+
//
|
|
69
|
+
A: () => (this.date.getHours() < 12 ? 'am' : 'pm'),
|
|
70
|
+
a: () => (this.date.getHours() < 12 ? 'am' : 'pm'),
|
|
71
|
+
date: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'shortDate')),
|
|
72
|
+
shortDate: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'shortDate')),
|
|
73
|
+
longDate: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'longDate')),
|
|
74
|
+
//
|
|
75
|
+
shortTime: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'shortTime')),
|
|
76
|
+
time: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'shortTime')),
|
|
77
|
+
longTime: (options) => this.format(this.getDateTimeFormatByLocale(options.locale, 'longTime')),
|
|
78
|
+
//
|
|
79
|
+
datetime: (options) => this.format('date time', { locale: options.locale }),
|
|
80
|
+
};
|
|
81
|
+
this._language = () => (isBrowser() ? navigator.language : 'en-GB');
|
|
82
|
+
this._calendar = calendar;
|
|
83
|
+
this._date = value;
|
|
84
|
+
}
|
|
85
|
+
clone() {
|
|
86
|
+
return new AXDateTime(this.date, this.calendar);
|
|
87
|
+
}
|
|
88
|
+
get dayOfMonth() {
|
|
89
|
+
return this._calendar.dayOfMonth(this.date);
|
|
90
|
+
}
|
|
91
|
+
get dayOfYear() {
|
|
92
|
+
return this._calendar.dayOfYear(this.date);
|
|
93
|
+
}
|
|
94
|
+
get dayOfWeek() {
|
|
95
|
+
return this._calendar.dayOfWeek(this.date);
|
|
96
|
+
}
|
|
97
|
+
get hour() {
|
|
98
|
+
return this._date.getHours();
|
|
99
|
+
}
|
|
100
|
+
get minute() {
|
|
101
|
+
return this._date.getMinutes();
|
|
102
|
+
}
|
|
103
|
+
get second() {
|
|
104
|
+
return this._date.getSeconds();
|
|
105
|
+
}
|
|
106
|
+
get year() {
|
|
107
|
+
return this._calendar.year(this.date);
|
|
108
|
+
}
|
|
109
|
+
get monthOfYear() {
|
|
110
|
+
return this._calendar.monthOfYear(this.date);
|
|
111
|
+
}
|
|
112
|
+
get weekOfYear() {
|
|
113
|
+
return this._calendar.weekOfYear(this.date);
|
|
114
|
+
}
|
|
115
|
+
get month() {
|
|
116
|
+
return new AXCalendarMonth(this);
|
|
117
|
+
}
|
|
118
|
+
add(unit, amount) {
|
|
119
|
+
return this._calendar.add(this.date, unit, amount);
|
|
120
|
+
}
|
|
121
|
+
set(unit = 'day', value) {
|
|
122
|
+
return this._calendar.set(this.date, unit, value);
|
|
123
|
+
}
|
|
124
|
+
duration(end) {
|
|
125
|
+
const date = end instanceof AXDateTime ? end.date : end;
|
|
126
|
+
const val = new AXDateTime(date, this.calendar);
|
|
127
|
+
const range = new AXDateTimeRange(this, val);
|
|
128
|
+
return range.duration();
|
|
129
|
+
}
|
|
130
|
+
startOf(unit = 'day') {
|
|
131
|
+
return this._calendar.startOf(this.date, unit);
|
|
132
|
+
}
|
|
133
|
+
endOf(unit = 'day') {
|
|
134
|
+
return this._calendar.endOf(this.date, unit);
|
|
135
|
+
}
|
|
136
|
+
format(format = this.getDateTimeFormatByLocale(this._language(), 'shortDate'), options) {
|
|
137
|
+
const effectiveOptions = defaults({}, options, {
|
|
138
|
+
locale: this._language(),
|
|
139
|
+
});
|
|
140
|
+
const re = new RegExp(orderBy(Object.keys(this._formatKeys), (c) => c.length, ['desc']).join('|'), 'gi');
|
|
141
|
+
return format.replace(re, (matched) => {
|
|
142
|
+
const f = this._formatKeys[matched];
|
|
143
|
+
const r = f(effectiveOptions);
|
|
144
|
+
return r;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
getDateTimeFormatByLocale(locale, style) {
|
|
148
|
+
let options = {};
|
|
149
|
+
switch (style) {
|
|
150
|
+
case 'shortDate': // Year, Month, Day
|
|
151
|
+
options = { year: 'numeric', month: '2-digit', day: '2-digit' };
|
|
152
|
+
break;
|
|
153
|
+
case 'longDate': // Weekday, Month name, Day, Year
|
|
154
|
+
options = {
|
|
155
|
+
weekday: 'long',
|
|
156
|
+
year: 'numeric',
|
|
157
|
+
month: 'long',
|
|
158
|
+
day: 'numeric',
|
|
159
|
+
};
|
|
160
|
+
break;
|
|
161
|
+
case 'shortTime': // Hour, Minute
|
|
162
|
+
options = { hour: '2-digit', minute: '2-digit', hour12: false };
|
|
163
|
+
break;
|
|
164
|
+
case 'longTime': // Hour, Minute, Second
|
|
165
|
+
options = {
|
|
166
|
+
hour: '2-digit',
|
|
167
|
+
minute: '2-digit',
|
|
168
|
+
second: '2-digit',
|
|
169
|
+
hour12: false,
|
|
170
|
+
};
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
const formatter = new Intl.DateTimeFormat(locale, options);
|
|
174
|
+
// Get parts of the date and/or time
|
|
175
|
+
const parts = formatter.formatToParts(new Date());
|
|
176
|
+
// Map parts to their respective format
|
|
177
|
+
const formatMap = {
|
|
178
|
+
day: 'dd',
|
|
179
|
+
month: style == 'longDate' ? 'MMMM' : 'MM',
|
|
180
|
+
year: 'yyyy',
|
|
181
|
+
hour: 'HH',
|
|
182
|
+
minute: 'mm',
|
|
183
|
+
second: 'ss',
|
|
184
|
+
weekday: 'E',
|
|
185
|
+
literal: '',
|
|
186
|
+
};
|
|
187
|
+
// Construct the date and/or time format string
|
|
188
|
+
return parts
|
|
189
|
+
.map((part) => {
|
|
190
|
+
if (part.type === 'literal') {
|
|
191
|
+
// Use the literal part directly as separator
|
|
192
|
+
return part.value;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
return formatMap[part.type] || part.value;
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
.join('');
|
|
199
|
+
}
|
|
200
|
+
pad(n, width, z = '0') {
|
|
201
|
+
n = n + '';
|
|
202
|
+
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
|
|
203
|
+
}
|
|
204
|
+
equal(value, unit = 'day') {
|
|
205
|
+
return this.compare(value, unit) == 0;
|
|
206
|
+
}
|
|
207
|
+
compare(value, unit = 'day') {
|
|
208
|
+
const date = value instanceof AXDateTime ? value.date : value;
|
|
209
|
+
const val = new AXDateTime(date, this.calendar);
|
|
210
|
+
const func = (v1, v2) => {
|
|
211
|
+
if (v1 == v2) {
|
|
212
|
+
return 0;
|
|
213
|
+
}
|
|
214
|
+
else if (v1 > v2) {
|
|
215
|
+
return 1;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
return -1;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
let p = 0;
|
|
222
|
+
switch (unit) {
|
|
223
|
+
case 'year':
|
|
224
|
+
return func(this.year, val.year);
|
|
225
|
+
case 'week':
|
|
226
|
+
p = this.compare(val, 'year');
|
|
227
|
+
return p == 0 ? func(this.weekOfYear, val.weekOfYear) : p;
|
|
228
|
+
case 'month':
|
|
229
|
+
p = this.compare(val, 'year');
|
|
230
|
+
return p == 0 ? func(this.monthOfYear, val.monthOfYear) : p;
|
|
231
|
+
case 'day':
|
|
232
|
+
p = this.compare(val, 'year');
|
|
233
|
+
return p == 0 ? func(this.dayOfYear, val.dayOfYear) : p;
|
|
234
|
+
case 'hour':
|
|
235
|
+
p = this.compare(val, 'day');
|
|
236
|
+
return p == 0 ? func(this.hour, val.hour) : p;
|
|
237
|
+
case 'minute':
|
|
238
|
+
p = this.compare(val, 'hour');
|
|
239
|
+
return p == 0 ? func(this.minute, val.minute) : p;
|
|
240
|
+
case 'second':
|
|
241
|
+
p = this.compare(val, 'minute');
|
|
242
|
+
return p == 0 ? func(this.second, val.second) : p;
|
|
243
|
+
default:
|
|
244
|
+
return func(this.date.getTime(), val.date.getTime());
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
class AXCalendarMonth {
|
|
249
|
+
get range() {
|
|
250
|
+
return this._range;
|
|
251
|
+
}
|
|
252
|
+
set range(v) {
|
|
253
|
+
this._range = v;
|
|
254
|
+
}
|
|
255
|
+
get totalDays() {
|
|
256
|
+
return this.range.endTime.dayOfMonth;
|
|
257
|
+
}
|
|
258
|
+
constructor(date) {
|
|
259
|
+
this.index = date.date.getMonth();
|
|
260
|
+
this.name = date.format('MMMM');
|
|
261
|
+
this.range = new AXDateTimeRange(new AXDateTime(date.startOf('month').date, date.calendar), new AXDateTime(date.endOf('month').date, date.calendar));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
class AXDateTimeRange {
|
|
265
|
+
get startTime() {
|
|
266
|
+
return this._startTime;
|
|
267
|
+
}
|
|
268
|
+
get endTime() {
|
|
269
|
+
return this._endTime;
|
|
270
|
+
}
|
|
271
|
+
constructor(startTime, endTime) {
|
|
272
|
+
this._startTime = startTime;
|
|
273
|
+
this._endTime = endTime;
|
|
274
|
+
}
|
|
275
|
+
duration() {
|
|
276
|
+
const result = {
|
|
277
|
+
miliseconds: 0,
|
|
278
|
+
seconds: 0,
|
|
279
|
+
minutes: 0,
|
|
280
|
+
hours: 0,
|
|
281
|
+
days: 0,
|
|
282
|
+
months: 0,
|
|
283
|
+
years: 0,
|
|
284
|
+
total: {
|
|
285
|
+
miliseconds: 0,
|
|
286
|
+
seconds: 0,
|
|
287
|
+
minutes: 0,
|
|
288
|
+
hours: 0,
|
|
289
|
+
days: 0,
|
|
290
|
+
weeks: 0,
|
|
291
|
+
months: 0,
|
|
292
|
+
years: 0,
|
|
293
|
+
},
|
|
294
|
+
};
|
|
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;
|
|
302
|
+
const startTime = this._startTime.date.getTime();
|
|
303
|
+
const endTime = this._endTime.date.getTime();
|
|
304
|
+
const diff = Math.abs(endTime - startTime);
|
|
305
|
+
//
|
|
306
|
+
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));
|
|
331
|
+
return result;
|
|
332
|
+
}
|
|
333
|
+
enumurate(unit = 'day', amount = 1) {
|
|
334
|
+
const result = [];
|
|
335
|
+
let item = this._startTime.clone();
|
|
336
|
+
while (item.compare(this._endTime, unit) < 1) {
|
|
337
|
+
if (!result.some((c) => c.equal(item, unit))) {
|
|
338
|
+
result.push(item);
|
|
339
|
+
}
|
|
340
|
+
item = item.add(unit, amount);
|
|
341
|
+
}
|
|
342
|
+
return result;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
class GeorgianCalendar extends AXCalendar {
|
|
347
|
+
/**
|
|
348
|
+
* @ignore
|
|
349
|
+
*/
|
|
350
|
+
constructor(config) {
|
|
351
|
+
super(config);
|
|
352
|
+
}
|
|
353
|
+
create(value) {
|
|
354
|
+
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
|
+
}
|
|
356
|
+
name() {
|
|
357
|
+
return 'georgian';
|
|
358
|
+
}
|
|
359
|
+
dayOfMonth(date) {
|
|
360
|
+
return date.getDate();
|
|
361
|
+
}
|
|
362
|
+
dayOfYear(date) {
|
|
363
|
+
let result = 0;
|
|
364
|
+
let m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
365
|
+
if (this.isLeap(date)) {
|
|
366
|
+
m[1] = 29;
|
|
367
|
+
}
|
|
368
|
+
for (let i = 0; i < date.getMonth(); i++) {
|
|
369
|
+
result = result + m[i];
|
|
370
|
+
}
|
|
371
|
+
result += date.getDate();
|
|
372
|
+
return result;
|
|
373
|
+
}
|
|
374
|
+
dayOfWeek(date) {
|
|
375
|
+
return date.getDay() + 1;
|
|
376
|
+
}
|
|
377
|
+
weekOfYear(date) {
|
|
378
|
+
const firstDay = new AXDateTime(date, this).startOf('year');
|
|
379
|
+
return Math.ceil(((date.getTime() - firstDay.date.getTime()) / 86400000 +
|
|
380
|
+
firstDay.date.getDay() +
|
|
381
|
+
1) /
|
|
382
|
+
7);
|
|
383
|
+
}
|
|
384
|
+
year(date) {
|
|
385
|
+
return date.getFullYear();
|
|
386
|
+
}
|
|
387
|
+
monthOfYear(date) {
|
|
388
|
+
return date.getMonth() + 1;
|
|
389
|
+
}
|
|
390
|
+
add(date, unit, amount) {
|
|
391
|
+
let value = date.valueOf();
|
|
392
|
+
switch (unit) {
|
|
393
|
+
case 'second':
|
|
394
|
+
value += 1000 * amount;
|
|
395
|
+
break;
|
|
396
|
+
case 'minute':
|
|
397
|
+
value += 60000 * amount;
|
|
398
|
+
break;
|
|
399
|
+
case 'hour':
|
|
400
|
+
value += 3600000 * amount;
|
|
401
|
+
break;
|
|
402
|
+
case 'month': {
|
|
403
|
+
const v = new Date(value);
|
|
404
|
+
// Calculate the new year and month considering the amount
|
|
405
|
+
let newYear = v.getFullYear();
|
|
406
|
+
let newMonth = v.getMonth() + amount;
|
|
407
|
+
// Adjust for year overflow or underflow
|
|
408
|
+
while (newMonth > 11) {
|
|
409
|
+
newMonth -= 12;
|
|
410
|
+
newYear++;
|
|
411
|
+
}
|
|
412
|
+
while (newMonth < 0) {
|
|
413
|
+
newMonth += 12;
|
|
414
|
+
newYear--;
|
|
415
|
+
}
|
|
416
|
+
// Set the date to the first of the month to prevent overflow
|
|
417
|
+
v.setDate(1);
|
|
418
|
+
v.setFullYear(newYear);
|
|
419
|
+
v.setMonth(newMonth);
|
|
420
|
+
// Get the last day of the new month
|
|
421
|
+
const lastDayOfMonth = new Date(newYear, newMonth + 1, 0).getDate();
|
|
422
|
+
// Set the date to either the original day or the last day of the new month, whichever is smaller
|
|
423
|
+
const originalDay = date.getDate();
|
|
424
|
+
v.setDate(Math.min(originalDay, lastDayOfMonth));
|
|
425
|
+
value = v.valueOf();
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
case 'week':
|
|
429
|
+
value += 7 * 86400000 * amount;
|
|
430
|
+
break;
|
|
431
|
+
case 'year': {
|
|
432
|
+
const newDate = new Date(value);
|
|
433
|
+
newDate.setFullYear(newDate.getFullYear() + amount);
|
|
434
|
+
// Handling for leap years: if the original date is February 29th, and the new year is not a leap year,
|
|
435
|
+
// set the date to February 28th.
|
|
436
|
+
if (date.getMonth() === 1 &&
|
|
437
|
+
date.getDate() === 29 &&
|
|
438
|
+
newDate.getMonth() !== 1) {
|
|
439
|
+
newDate.setMonth(1);
|
|
440
|
+
newDate.setDate(28);
|
|
441
|
+
}
|
|
442
|
+
value = newDate.valueOf();
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
case 'day':
|
|
446
|
+
default:
|
|
447
|
+
value += 86400000 * amount;
|
|
448
|
+
}
|
|
449
|
+
return new AXDateTime(new Date(value), this);
|
|
450
|
+
}
|
|
451
|
+
set(date, unit, value) {
|
|
452
|
+
const clone = new Date(date.valueOf());
|
|
453
|
+
switch (unit) {
|
|
454
|
+
case 'second':
|
|
455
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), value, clone.getMilliseconds());
|
|
456
|
+
break;
|
|
457
|
+
case 'minute':
|
|
458
|
+
clone.setHours(clone.getHours(), value, clone.getSeconds(), clone.getMilliseconds());
|
|
459
|
+
break;
|
|
460
|
+
case 'hour':
|
|
461
|
+
clone.setHours(value, clone.getMinutes(), clone.getSeconds(), clone.getMilliseconds());
|
|
462
|
+
break;
|
|
463
|
+
default:
|
|
464
|
+
case 'day':
|
|
465
|
+
clone.setDate(value);
|
|
466
|
+
break;
|
|
467
|
+
case 'week':
|
|
468
|
+
break;
|
|
469
|
+
case 'month':
|
|
470
|
+
clone.setMonth(Math.max(0, value - 1));
|
|
471
|
+
break;
|
|
472
|
+
case 'year':
|
|
473
|
+
clone.setFullYear(value);
|
|
474
|
+
break;
|
|
475
|
+
}
|
|
476
|
+
return new AXDateTime(clone, this);
|
|
477
|
+
}
|
|
478
|
+
startOf(date, unit) {
|
|
479
|
+
const clone = new Date(date.valueOf());
|
|
480
|
+
switch (unit) {
|
|
481
|
+
case 'second':
|
|
482
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), clone.getSeconds(), 0);
|
|
483
|
+
return new AXDateTime(clone, this);
|
|
484
|
+
case 'minute':
|
|
485
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), 0, 0);
|
|
486
|
+
return new AXDateTime(clone, this);
|
|
487
|
+
case 'hour':
|
|
488
|
+
clone.setHours(clone.getHours(), 0, 0, 0);
|
|
489
|
+
return new AXDateTime(clone, this);
|
|
490
|
+
default:
|
|
491
|
+
case 'day':
|
|
492
|
+
clone.setHours(0, 0, 0, 0);
|
|
493
|
+
return new AXDateTime(clone, this);
|
|
494
|
+
case 'week': {
|
|
495
|
+
const start = 1; // Week starts on Monday
|
|
496
|
+
const day = clone.getDay();
|
|
497
|
+
const diff = clone.getDate() - day + (day == 0 ? -6 : start - day);
|
|
498
|
+
clone.setDate(diff);
|
|
499
|
+
clone.setHours(0, 0, 0, 0);
|
|
500
|
+
return new AXDateTime(clone, this);
|
|
501
|
+
}
|
|
502
|
+
case 'month':
|
|
503
|
+
clone.setDate(1);
|
|
504
|
+
return new AXDateTime(clone, this).startOf('day');
|
|
505
|
+
case 'year':
|
|
506
|
+
clone.setMonth(0);
|
|
507
|
+
clone.setDate(1);
|
|
508
|
+
return new AXDateTime(clone, this).startOf('day');
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
endOf(date, unit) {
|
|
512
|
+
const clone = new Date(date.valueOf());
|
|
513
|
+
switch (unit) {
|
|
514
|
+
case 'second':
|
|
515
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), clone.getSeconds(), 999);
|
|
516
|
+
return new AXDateTime(clone, this);
|
|
517
|
+
case 'minute':
|
|
518
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), 59, 999);
|
|
519
|
+
return new AXDateTime(clone, this);
|
|
520
|
+
case 'hour':
|
|
521
|
+
clone.setHours(clone.getHours(), 59, 59, 999);
|
|
522
|
+
return new AXDateTime(clone, this);
|
|
523
|
+
default:
|
|
524
|
+
case 'day':
|
|
525
|
+
clone.setHours(23, 59, 59, 999);
|
|
526
|
+
return new AXDateTime(clone, this);
|
|
527
|
+
case 'week':
|
|
528
|
+
return this.startOf(date, 'week').add('day', 6).endOf('day');
|
|
529
|
+
case 'month': {
|
|
530
|
+
const dateObj = new Date(date.getFullYear(), date.getMonth() + 1, 0);
|
|
531
|
+
dateObj.setHours(23, 59, 59, 999);
|
|
532
|
+
return new AXDateTime(dateObj, this);
|
|
533
|
+
}
|
|
534
|
+
case 'year':
|
|
535
|
+
clone.setMonth(11);
|
|
536
|
+
return new AXDateTime(clone, this).endOf('month');
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
isLeap(date) {
|
|
540
|
+
let leapYear = new Date(date.getFullYear(), 1, 29);
|
|
541
|
+
return leapYear.getDate() == 29;
|
|
542
|
+
}
|
|
543
|
+
parse(value) {
|
|
544
|
+
return new AXDateTime(new Date(value), this);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
class JalaliCalendar extends AXCalendar {
|
|
549
|
+
/**
|
|
550
|
+
* @ignore
|
|
551
|
+
*/
|
|
552
|
+
constructor(config) {
|
|
553
|
+
super(config);
|
|
554
|
+
/*
|
|
555
|
+
Jalaali years starting the 33-year rule.
|
|
556
|
+
*/
|
|
557
|
+
this.breaks = [
|
|
558
|
+
-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210, 1635, 2060, 2097,
|
|
559
|
+
2192, 2262, 2324, 2394, 2456, 3178,
|
|
560
|
+
];
|
|
561
|
+
}
|
|
562
|
+
create(value) {
|
|
563
|
+
const a = this.toGregorian(value.year, value.month, value.date);
|
|
564
|
+
return new AXDateTime(new Date(a.getFullYear(), a.getMonth(), a.getDate(), value.hours || 0, value.minutes || 0, value.seconds || 0, value.ms || 0), this);
|
|
565
|
+
}
|
|
566
|
+
name() {
|
|
567
|
+
return 'jalali';
|
|
568
|
+
}
|
|
569
|
+
dayOfMonth(date) {
|
|
570
|
+
return this.toJalaali(date).day;
|
|
571
|
+
}
|
|
572
|
+
dayOfYear(date) {
|
|
573
|
+
const j = this.toJalaali(date);
|
|
574
|
+
return ((j.month <= 6 ? (j.month - 1) * 31 : 6 * 31 + (j.month - 7) * 30) + j.day);
|
|
575
|
+
}
|
|
576
|
+
dayOfWeek(date) {
|
|
577
|
+
return date.getDay() == 6 ? 1 : date.getDay() + 2;
|
|
578
|
+
}
|
|
579
|
+
weekOfYear(date) {
|
|
580
|
+
//TODO : apply jalali
|
|
581
|
+
const firstDay = new AXDateTime(date, this).startOf('year');
|
|
582
|
+
return Math.ceil(((date.getTime() - firstDay.date.getTime()) / 86400000 +
|
|
583
|
+
firstDay.date.getDay() +
|
|
584
|
+
1) /
|
|
585
|
+
7);
|
|
586
|
+
}
|
|
587
|
+
year(date) {
|
|
588
|
+
return this.toJalaali(date).year;
|
|
589
|
+
}
|
|
590
|
+
monthOfYear(date) {
|
|
591
|
+
return this.toJalaali(date).month;
|
|
592
|
+
}
|
|
593
|
+
add(date, unit, amount) {
|
|
594
|
+
let value = date.valueOf();
|
|
595
|
+
switch (unit) {
|
|
596
|
+
case 'second':
|
|
597
|
+
value += 1000 * amount;
|
|
598
|
+
break;
|
|
599
|
+
case 'minute':
|
|
600
|
+
value += 60000 * amount;
|
|
601
|
+
break;
|
|
602
|
+
case 'hour':
|
|
603
|
+
value += 3600000 * amount;
|
|
604
|
+
break;
|
|
605
|
+
case 'month': {
|
|
606
|
+
// const v = new Date(value);
|
|
607
|
+
// let jd = this.dayOfMonth(date);
|
|
608
|
+
// let jm = this.monthOfYear(date);
|
|
609
|
+
// let jy = this.year(date);
|
|
610
|
+
// const nm = jm + amount;
|
|
611
|
+
// const ny = nm % 12 ? Math.floor(nm / 12) : 0;
|
|
612
|
+
// jy += ny;
|
|
613
|
+
// jm = nm - ny * 12;
|
|
614
|
+
// const vv = this.toGregorian(jy, jm, jd);
|
|
615
|
+
// v.setFullYear(vv.getFullYear());
|
|
616
|
+
// v.setMonth(vv.getMonth());
|
|
617
|
+
// v.setDate(vv.getDate());
|
|
618
|
+
// value = v.valueOf();
|
|
619
|
+
// break;
|
|
620
|
+
let jd = this.dayOfMonth(date);
|
|
621
|
+
let jm = this.monthOfYear(date);
|
|
622
|
+
let jy = this.year(date);
|
|
623
|
+
let newMonth = jm + amount;
|
|
624
|
+
let yearsToAdd = Math.floor(newMonth / 12);
|
|
625
|
+
newMonth = newMonth % 12;
|
|
626
|
+
if (newMonth <= 0) {
|
|
627
|
+
newMonth += 12;
|
|
628
|
+
yearsToAdd--;
|
|
629
|
+
}
|
|
630
|
+
jy += yearsToAdd;
|
|
631
|
+
// Temporary set to first of the month to prevent rollover
|
|
632
|
+
const tempDate = this.toGregorian(jy, newMonth, 1);
|
|
633
|
+
const gregorianDate = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate());
|
|
634
|
+
// Adjust the day to either the original day or the last day of the new month, whichever is smaller
|
|
635
|
+
const lastDayOfNewMonth = this.jalaaliMonthLength(jy, newMonth); // Implement this method to find the last day in a Jalali month
|
|
636
|
+
jd = Math.min(jd, lastDayOfNewMonth);
|
|
637
|
+
const finalDate = this.toGregorian(jy, newMonth, jd);
|
|
638
|
+
gregorianDate.setFullYear(finalDate.getFullYear());
|
|
639
|
+
gregorianDate.setMonth(finalDate.getMonth());
|
|
640
|
+
gregorianDate.setDate(finalDate.getDate());
|
|
641
|
+
value = gregorianDate.valueOf();
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
case 'week':
|
|
645
|
+
value += 7 * 86400000 * amount;
|
|
646
|
+
break;
|
|
647
|
+
case 'year': {
|
|
648
|
+
const v = new Date(value);
|
|
649
|
+
let jd = this.dayOfMonth(date);
|
|
650
|
+
let jm = this.monthOfYear(date);
|
|
651
|
+
let jy = this.year(date);
|
|
652
|
+
const vv = this.toGregorian(jy + amount, jm, jd);
|
|
653
|
+
v.setFullYear(vv.getFullYear());
|
|
654
|
+
v.setMonth(vv.getMonth());
|
|
655
|
+
v.setDate(vv.getDate());
|
|
656
|
+
value = v.valueOf();
|
|
657
|
+
break;
|
|
658
|
+
}
|
|
659
|
+
case 'day':
|
|
660
|
+
default:
|
|
661
|
+
value += 86400000 * amount;
|
|
662
|
+
}
|
|
663
|
+
return new AXDateTime(new Date(value), this);
|
|
664
|
+
}
|
|
665
|
+
set(date, unit, value) {
|
|
666
|
+
const clone = new Date(date.valueOf());
|
|
667
|
+
const jDate = this.toJalaali(clone);
|
|
668
|
+
switch (unit) {
|
|
669
|
+
case 'second':
|
|
670
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), value, clone.getMilliseconds());
|
|
671
|
+
break;
|
|
672
|
+
case 'minute':
|
|
673
|
+
clone.setHours(clone.getHours(), value, clone.getSeconds(), clone.getMilliseconds());
|
|
674
|
+
break;
|
|
675
|
+
case 'hour':
|
|
676
|
+
clone.setHours(value, clone.getMinutes(), clone.getSeconds(), clone.getMilliseconds());
|
|
677
|
+
break;
|
|
678
|
+
default:
|
|
679
|
+
case 'day': {
|
|
680
|
+
const gDate = this.toGregorian(jDate.year, jDate.month, value);
|
|
681
|
+
clone.setDate(gDate.getDate());
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
684
|
+
case 'week':
|
|
685
|
+
break;
|
|
686
|
+
case 'month': {
|
|
687
|
+
const gDate2 = this.toGregorian(jDate.year, value, jDate.day);
|
|
688
|
+
clone.setMonth(gDate2.getMonth());
|
|
689
|
+
break;
|
|
690
|
+
}
|
|
691
|
+
case 'year': {
|
|
692
|
+
const gDate3 = this.toGregorian(value, jDate.month, jDate.day);
|
|
693
|
+
clone.setFullYear(gDate3.getFullYear());
|
|
694
|
+
break;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
return new AXDateTime(clone, this);
|
|
698
|
+
}
|
|
699
|
+
startOf(date, unit) {
|
|
700
|
+
const clone = new Date(date.valueOf());
|
|
701
|
+
switch (unit) {
|
|
702
|
+
case 'second':
|
|
703
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), clone.getSeconds(), 0);
|
|
704
|
+
return new AXDateTime(clone, this);
|
|
705
|
+
case 'minute':
|
|
706
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), 0, 0);
|
|
707
|
+
return new AXDateTime(clone, this);
|
|
708
|
+
case 'hour':
|
|
709
|
+
clone.setHours(clone.getHours(), 0, 0, 0);
|
|
710
|
+
return new AXDateTime(clone, this);
|
|
711
|
+
default:
|
|
712
|
+
case 'day':
|
|
713
|
+
clone.setHours(0, 0, 0, 0);
|
|
714
|
+
return new AXDateTime(clone, this);
|
|
715
|
+
case 'week':
|
|
716
|
+
return new AXDateTime(clone, this)
|
|
717
|
+
.add('day', -this.dayOfWeek(clone) + 1)
|
|
718
|
+
.startOf('day');
|
|
719
|
+
case 'month': {
|
|
720
|
+
const jy = this.year(date);
|
|
721
|
+
const jm = this.monthOfYear(date);
|
|
722
|
+
const gDate = this.toGregorian(jy, jm, 1);
|
|
723
|
+
return new AXDateTime(gDate, this).startOf('day');
|
|
724
|
+
}
|
|
725
|
+
case 'year': {
|
|
726
|
+
const jy = this.year(date);
|
|
727
|
+
const gDate = this.toGregorian(jy, 1, 1);
|
|
728
|
+
return new AXDateTime(gDate, this).startOf('day');
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
endOf(date, unit) {
|
|
733
|
+
const clone = new Date(date.valueOf());
|
|
734
|
+
switch (unit) {
|
|
735
|
+
case 'second':
|
|
736
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), clone.getSeconds(), 999);
|
|
737
|
+
return new AXDateTime(clone, this);
|
|
738
|
+
case 'minute':
|
|
739
|
+
clone.setHours(clone.getHours(), clone.getMinutes(), 59, 999);
|
|
740
|
+
return new AXDateTime(clone, this);
|
|
741
|
+
case 'hour':
|
|
742
|
+
clone.setHours(clone.getHours(), 59, 59, 999);
|
|
743
|
+
return new AXDateTime(clone, this);
|
|
744
|
+
default:
|
|
745
|
+
case 'day':
|
|
746
|
+
clone.setHours(23, 59, 59, 999);
|
|
747
|
+
return new AXDateTime(clone, this);
|
|
748
|
+
case 'week': {
|
|
749
|
+
return this.startOf(date, 'week').add('day', 6).endOf('day');
|
|
750
|
+
}
|
|
751
|
+
case 'month': {
|
|
752
|
+
const jy = this.year(date);
|
|
753
|
+
const jm = this.monthOfYear(date);
|
|
754
|
+
const jd = this.jalaaliMonthLength(jy, jm);
|
|
755
|
+
const gDate = this.toGregorian(jy, jm, jd);
|
|
756
|
+
return new AXDateTime(gDate, this).endOf('day');
|
|
757
|
+
}
|
|
758
|
+
case 'year': {
|
|
759
|
+
const jy = this.year(date);
|
|
760
|
+
const gDate = this.toGregorian(jy, 12, this.jalaaliMonthLength(jy, 12));
|
|
761
|
+
return new AXDateTime(gDate, this).endOf('day');
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
parse(value) {
|
|
766
|
+
const [y, M, d, h, m, s, ms] = value.split(/[^a-zA-Z0-9]+/gi);
|
|
767
|
+
const date = this.toGregorian(Number(y) ?? 0, Number(M) ?? 1, Number(d) ?? 1);
|
|
768
|
+
if (h != null)
|
|
769
|
+
date.setHours(Number(h));
|
|
770
|
+
if (m != null)
|
|
771
|
+
date.setMinutes(Number(m));
|
|
772
|
+
if (s != null)
|
|
773
|
+
date.setSeconds(Number(s));
|
|
774
|
+
if (ms != null)
|
|
775
|
+
date.setMilliseconds(Number(d));
|
|
776
|
+
return new AXDateTime(date, this);
|
|
777
|
+
}
|
|
778
|
+
/*
|
|
779
|
+
Converts a Gregorian date to Jalaali.
|
|
780
|
+
*/
|
|
781
|
+
toJalaali(date) {
|
|
782
|
+
const gd = date.getDate();
|
|
783
|
+
const gm = date.getMonth() + 1;
|
|
784
|
+
const gy = date.getFullYear();
|
|
785
|
+
const r = this.d2j(this.g2d(gy, gm, gd));
|
|
786
|
+
return {
|
|
787
|
+
year: r.jy,
|
|
788
|
+
month: r.jm,
|
|
789
|
+
day: r.jd,
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
/*
|
|
793
|
+
Converts a Jalaali date to Gregorian.
|
|
794
|
+
*/
|
|
795
|
+
toGregorian(jy, jm, jd) {
|
|
796
|
+
const g = this.d2g(this.j2d(jy, jm, jd));
|
|
797
|
+
return new Date(g.gy, g.gm - 1, g.gd);
|
|
798
|
+
}
|
|
799
|
+
/*
|
|
800
|
+
Checks whether a Jalaali date is valid or not.
|
|
801
|
+
*/
|
|
802
|
+
isValidJalaaliDate(jy, jm, jd) {
|
|
803
|
+
return (jy >= -61 &&
|
|
804
|
+
jy <= 3177 &&
|
|
805
|
+
jm >= 1 &&
|
|
806
|
+
jm <= 12 &&
|
|
807
|
+
jd >= 1 &&
|
|
808
|
+
jd <= this.jalaaliMonthLength(jy, jm));
|
|
809
|
+
}
|
|
810
|
+
/*
|
|
811
|
+
Is this a leap year or not?
|
|
812
|
+
*/
|
|
813
|
+
isLeapJalaaliYear(jy) {
|
|
814
|
+
return this.jalCalLeap(jy) === 0;
|
|
815
|
+
}
|
|
816
|
+
/*
|
|
817
|
+
Number of days in a given month in a Jalaali year.
|
|
818
|
+
*/
|
|
819
|
+
jalaaliMonthLength(jy, jm) {
|
|
820
|
+
if (jm <= 6)
|
|
821
|
+
return 31;
|
|
822
|
+
if (jm <= 11)
|
|
823
|
+
return 30;
|
|
824
|
+
if (this.isLeapJalaaliYear(jy))
|
|
825
|
+
return 30;
|
|
826
|
+
return 29;
|
|
827
|
+
}
|
|
828
|
+
/*
|
|
829
|
+
This determines if the Jalaali (Persian) year is
|
|
830
|
+
leap (366-day long) or is the common year (365 days)
|
|
831
|
+
|
|
832
|
+
@param jy Jalaali calendar year (-61 to 3177)
|
|
833
|
+
@returns number of years since the last leap year (0 to 4)
|
|
834
|
+
*/
|
|
835
|
+
jalCalLeap(jy) {
|
|
836
|
+
let bl = this.breaks.length, jp = this.breaks[0], jm, jump, leap, n, i;
|
|
837
|
+
if (jy < jp || jy >= this.breaks[bl - 1])
|
|
838
|
+
throw new Error('Invalid Jalaali year ' + jy);
|
|
839
|
+
for (i = 1; i < bl; i += 1) {
|
|
840
|
+
jm = this.breaks[i];
|
|
841
|
+
jump = jm - jp;
|
|
842
|
+
if (jy < jm)
|
|
843
|
+
break;
|
|
844
|
+
jp = jm;
|
|
845
|
+
}
|
|
846
|
+
n = jy - jp;
|
|
847
|
+
if (jump - n < 6)
|
|
848
|
+
n = n - jump + this.div(jump + 4, 33) * 33;
|
|
849
|
+
leap = this.mod(this.mod(n + 1, 33) - 1, 4);
|
|
850
|
+
if (leap === -1) {
|
|
851
|
+
leap = 4;
|
|
852
|
+
}
|
|
853
|
+
return leap;
|
|
854
|
+
}
|
|
855
|
+
jalCal(jy, withoutLeap) {
|
|
856
|
+
let bl = this.breaks.length, gy = jy + 621, leapJ = -14, jp = this.breaks[0], jm, jump, leap, leapG, march, n, i;
|
|
857
|
+
if (jy < jp || jy >= this.breaks[bl - 1])
|
|
858
|
+
throw new Error('Invalid Jalaali year ' + jy);
|
|
859
|
+
// Find the limiting years for the Jalaali year jy.
|
|
860
|
+
for (i = 1; i < bl; i += 1) {
|
|
861
|
+
jm = this.breaks[i];
|
|
862
|
+
jump = jm - jp;
|
|
863
|
+
if (jy < jm)
|
|
864
|
+
break;
|
|
865
|
+
leapJ = leapJ + this.div(jump, 33) * 8 + this.div(this.mod(jump, 33), 4);
|
|
866
|
+
jp = jm;
|
|
867
|
+
}
|
|
868
|
+
n = jy - jp;
|
|
869
|
+
// Find the number of leap years from AD 621 to the beginning
|
|
870
|
+
// of the current Jalaali year in the Persian calendar.
|
|
871
|
+
leapJ = leapJ + this.div(n, 33) * 8 + this.div(this.mod(n, 33) + 3, 4);
|
|
872
|
+
if (this.mod(jump, 33) === 4 && jump - n === 4)
|
|
873
|
+
leapJ += 1;
|
|
874
|
+
// And the same in the Gregorian calendar (until the year gy).
|
|
875
|
+
leapG = this.div(gy, 4) - this.div((this.div(gy, 100) + 1) * 3, 4) - 150;
|
|
876
|
+
// Determine the Gregorian date of Farvardin the 1st.
|
|
877
|
+
march = 20 + leapJ - leapG;
|
|
878
|
+
// return with gy and march when we don't need leap
|
|
879
|
+
if (withoutLeap)
|
|
880
|
+
return { gy: gy, march: march };
|
|
881
|
+
// Find how many years have passed since the last leap year.
|
|
882
|
+
if (jump - n < 6)
|
|
883
|
+
n = n - jump + this.div(jump + 4, 33) * 33;
|
|
884
|
+
leap = this.mod(this.mod(n + 1, 33) - 1, 4);
|
|
885
|
+
if (leap === -1) {
|
|
886
|
+
leap = 4;
|
|
887
|
+
}
|
|
888
|
+
return {
|
|
889
|
+
leap: leap,
|
|
890
|
+
gy: gy,
|
|
891
|
+
march: march,
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
j2d(jy, jm, jd) {
|
|
895
|
+
let r = this.jalCal(jy, true);
|
|
896
|
+
return (this.g2d(r.gy, 3, r.march) +
|
|
897
|
+
(jm - 1) * 31 -
|
|
898
|
+
this.div(jm, 7) * (jm - 7) +
|
|
899
|
+
jd -
|
|
900
|
+
1);
|
|
901
|
+
}
|
|
902
|
+
d2j(jdn) {
|
|
903
|
+
let gy = this.d2g(jdn).gy, // Calculate Gregorian year (gy).
|
|
904
|
+
jy = gy - 621, r = this.jalCal(jy, false), jdn1f = this.g2d(gy, 3, r.march), jd, jm, k;
|
|
905
|
+
// Find number of days that passed since 1 Farvardin.
|
|
906
|
+
k = jdn - jdn1f;
|
|
907
|
+
if (k >= 0) {
|
|
908
|
+
if (k <= 185) {
|
|
909
|
+
// The first 6 months.
|
|
910
|
+
jm = 1 + this.div(k, 31);
|
|
911
|
+
jd = this.mod(k, 31) + 1;
|
|
912
|
+
return {
|
|
913
|
+
jy: jy,
|
|
914
|
+
jm: jm,
|
|
915
|
+
jd: jd,
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
else {
|
|
919
|
+
// The remaining months.
|
|
920
|
+
k -= 186;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
else {
|
|
924
|
+
// Previous Jalaali year.
|
|
925
|
+
jy -= 1;
|
|
926
|
+
k += 179;
|
|
927
|
+
if (r.leap === 1)
|
|
928
|
+
k += 1;
|
|
929
|
+
}
|
|
930
|
+
jm = 7 + this.div(k, 30);
|
|
931
|
+
jd = this.mod(k, 30) + 1;
|
|
932
|
+
return {
|
|
933
|
+
jy: jy,
|
|
934
|
+
jm: jm,
|
|
935
|
+
jd: jd,
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
g2d(gy, gm, gd) {
|
|
939
|
+
let d = this.div((gy + this.div(gm - 8, 6) + 100100) * 1461, 4) +
|
|
940
|
+
this.div(153 * this.mod(gm + 9, 12) + 2, 5) +
|
|
941
|
+
gd -
|
|
942
|
+
34840408;
|
|
943
|
+
d =
|
|
944
|
+
d -
|
|
945
|
+
this.div(this.div(gy + 100100 + this.div(gm - 8, 6), 100) * 3, 4) +
|
|
946
|
+
752;
|
|
947
|
+
return d;
|
|
948
|
+
}
|
|
949
|
+
d2g(jdn) {
|
|
950
|
+
let j, i, gd, gm, gy;
|
|
951
|
+
j = 4 * jdn + 139361631;
|
|
952
|
+
j = j + this.div(this.div(4 * jdn + 183187720, 146097) * 3, 4) * 4 - 3908;
|
|
953
|
+
i = this.div(this.mod(j, 1461), 4) * 5 + 308;
|
|
954
|
+
gd = this.div(this.mod(i, 153), 5) + 1;
|
|
955
|
+
gm = this.mod(this.div(i, 153), 12) + 1;
|
|
956
|
+
gy = this.div(j, 1461) - 100100 + this.div(8 - gm, 6);
|
|
957
|
+
return {
|
|
958
|
+
gy: gy,
|
|
959
|
+
gm: gm,
|
|
960
|
+
gd: gd,
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
jalaaliWeek(jy, jm, jd) {
|
|
964
|
+
let dayOfWeek = this.jalaaliToDateObject(jy, jm, jd, 0, 0, 0, 0).getDay();
|
|
965
|
+
let startDayDifference = dayOfWeek == 6 ? 0 : -(dayOfWeek + 1);
|
|
966
|
+
let endDayDifference = 6 + startDayDifference;
|
|
967
|
+
return {
|
|
968
|
+
saturday: this.d2j(this.j2d(jy, jm, jd + startDayDifference)),
|
|
969
|
+
friday: this.d2j(this.j2d(jy, jm, jd + endDayDifference)),
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
jalaaliToDateObject(jy, jm, jd, h = 0, m = 0, s = 0, ms = 0) {
|
|
973
|
+
let gregorianCalenderDate = this.toGregorian(jy, jm, jd);
|
|
974
|
+
return new Date(gregorianCalenderDate.getFullYear(), gregorianCalenderDate.getMonth() - 1, gregorianCalenderDate.getDate(), h || 0, m || 0, s || 0, ms || 0);
|
|
975
|
+
}
|
|
976
|
+
/*
|
|
977
|
+
Utility helper functions.
|
|
978
|
+
*/
|
|
979
|
+
div(a, b) {
|
|
980
|
+
return ~~(a / b);
|
|
981
|
+
}
|
|
982
|
+
mod(a, b) {
|
|
983
|
+
return a - ~~(a / b) * b;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
const AX_DATETIME_CONFIG = new InjectionToken('AX_DATETIME_CONFIG', {
|
|
988
|
+
providedIn: 'root',
|
|
989
|
+
factory: () => {
|
|
990
|
+
const global = inject(AX_GLOBAL_CONFIG);
|
|
991
|
+
set(global, 'dateTime', AX_DATETIME_CONFIG);
|
|
992
|
+
return AXDateTimeDefaultConfig;
|
|
993
|
+
},
|
|
994
|
+
});
|
|
995
|
+
const AXDateTimeDefaultConfig = {
|
|
996
|
+
calendar: 'georgian',
|
|
997
|
+
calendars: {
|
|
998
|
+
georgian: new GeorgianCalendar({
|
|
999
|
+
weekdays: [0, 1, 2, 3, 4, 5, 6],
|
|
1000
|
+
weekend: [5, 6],
|
|
1001
|
+
formats: {
|
|
1002
|
+
dateInput: 'yyyy/MM/dd',
|
|
1003
|
+
timeInput: 'HH:mm',
|
|
1004
|
+
dateTimeInput: 'yyyy/MM/dd HH:mm',
|
|
1005
|
+
dateDisplay: 'DDDD, d MMM yyyy',
|
|
1006
|
+
timeDisplay: 'HH:mm',
|
|
1007
|
+
dateTimeDisplay: 'DDDD, d MMM yyyy HH:mm',
|
|
1008
|
+
},
|
|
1009
|
+
}),
|
|
1010
|
+
jalali: new JalaliCalendar({
|
|
1011
|
+
weekdays: [6, 0, 1, 2, 3, 4, 5],
|
|
1012
|
+
weekend: [6],
|
|
1013
|
+
formats: {
|
|
1014
|
+
dateInput: 'yyyy/MM/dd',
|
|
1015
|
+
timeInput: 'HH:mm',
|
|
1016
|
+
dateTimeInput: 'yyyy/MM/dd HH:mm',
|
|
1017
|
+
dateDisplay: 'DDDD, d MMM yyyy',
|
|
1018
|
+
timeDisplay: 'HH:mm',
|
|
1019
|
+
dateTimeDisplay: 'DDDD, d MMM yyyy HH:mm',
|
|
1020
|
+
},
|
|
1021
|
+
}),
|
|
1022
|
+
},
|
|
1023
|
+
};
|
|
1024
|
+
function dateTimeConfig(config = {}) {
|
|
1025
|
+
const result = {
|
|
1026
|
+
...AXDateTimeDefaultConfig,
|
|
1027
|
+
...config,
|
|
1028
|
+
};
|
|
1029
|
+
return result;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
class AXHolidaysLoaderDefault {
|
|
1033
|
+
getHolidays(options) {
|
|
1034
|
+
return Promise.resolve([]);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
const AX_DATETIME_HOLIDAYS_LOADER = new InjectionToken('AX_DATETIME_HOLIDAYS_LOADER', {
|
|
1038
|
+
providedIn: 'root',
|
|
1039
|
+
factory: () => {
|
|
1040
|
+
return new AXHolidaysLoaderDefault();
|
|
1041
|
+
},
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1044
|
+
class AXCalendarService {
|
|
1045
|
+
get calendar() {
|
|
1046
|
+
return this.getActiveCalendar();
|
|
1047
|
+
}
|
|
1048
|
+
getDefaultCalendar() {
|
|
1049
|
+
return this.config.calendars[this.config.calendar];
|
|
1050
|
+
}
|
|
1051
|
+
getActiveCalendar() {
|
|
1052
|
+
return this.activeCalendar.getValue();
|
|
1053
|
+
}
|
|
1054
|
+
setActiveCalendar(name) {
|
|
1055
|
+
if (name != this.calendar.name()) {
|
|
1056
|
+
const calendar = this.resolveCalendar(name);
|
|
1057
|
+
this.activeCalendar.next(calendar);
|
|
1058
|
+
this.eventService.emitEvent({
|
|
1059
|
+
type: AXEventTypes.AXCalendarChanged,
|
|
1060
|
+
payload: this.getActiveCalendar(),
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
get holidays() {
|
|
1065
|
+
return this._holidays;
|
|
1066
|
+
}
|
|
1067
|
+
constructor() {
|
|
1068
|
+
this.config = inject(AX_DATETIME_CONFIG);
|
|
1069
|
+
this._holidaysLoader = inject(AX_DATETIME_HOLIDAYS_LOADER);
|
|
1070
|
+
this.eventService = inject(AXEventService);
|
|
1071
|
+
this.activeCalendar = new BehaviorSubject(this.getDefaultCalendar());
|
|
1072
|
+
this.calendarChanges$ = this.activeCalendar.asObservable();
|
|
1073
|
+
this.onHolidaysChanged = new Subject();
|
|
1074
|
+
this._holidays = [];
|
|
1075
|
+
this.loadHolidays();
|
|
1076
|
+
}
|
|
1077
|
+
loadHolidays(options) {
|
|
1078
|
+
return this._holidaysLoader.getHolidays(options).then((value) => {
|
|
1079
|
+
this._holidays = value;
|
|
1080
|
+
this.onHolidaysChanged.next(this._holidays);
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
create(value, calendarName) {
|
|
1084
|
+
const calendar = calendarName
|
|
1085
|
+
? this.resolveCalendar(calendarName)
|
|
1086
|
+
: this.calendar;
|
|
1087
|
+
if (value instanceof Date) {
|
|
1088
|
+
return new AXDateTime(value, calendar);
|
|
1089
|
+
}
|
|
1090
|
+
else if (value?.year && value?.month) {
|
|
1091
|
+
return calendar.create(value);
|
|
1092
|
+
}
|
|
1093
|
+
return this.now();
|
|
1094
|
+
}
|
|
1095
|
+
now(calendarName) {
|
|
1096
|
+
const calendar = calendarName
|
|
1097
|
+
? this.resolveCalendar(calendarName)
|
|
1098
|
+
: this.calendar;
|
|
1099
|
+
return new AXDateTime(new Date(), calendar);
|
|
1100
|
+
}
|
|
1101
|
+
resolveCalendar(name) {
|
|
1102
|
+
const c = this.config.calendars[name];
|
|
1103
|
+
if (!c) {
|
|
1104
|
+
console.error(`"${name}" is not a valid calendar name!`);
|
|
1105
|
+
return this.calendar;
|
|
1106
|
+
}
|
|
1107
|
+
return c;
|
|
1108
|
+
}
|
|
1109
|
+
convert(value, calendarName) {
|
|
1110
|
+
const isISOString = (str) => {
|
|
1111
|
+
if (!/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(.\d{3}Z)?/.test(str))
|
|
1112
|
+
return false;
|
|
1113
|
+
const d = new Date(str);
|
|
1114
|
+
return d instanceof Date && !isNaN(d.getTime()); // valid date
|
|
1115
|
+
};
|
|
1116
|
+
//
|
|
1117
|
+
const calendar = calendarName
|
|
1118
|
+
? this.resolveCalendar(calendarName)
|
|
1119
|
+
: this.calendar;
|
|
1120
|
+
if (typeof value === 'string') {
|
|
1121
|
+
if (isISOString(value))
|
|
1122
|
+
return new AXDateTime(new Date(value), calendar);
|
|
1123
|
+
else
|
|
1124
|
+
return calendar.parse(value);
|
|
1125
|
+
}
|
|
1126
|
+
const date = value instanceof AXDateTime ? value.date : value;
|
|
1127
|
+
return new AXDateTime(date, calendar);
|
|
1128
|
+
}
|
|
1129
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXCalendarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1130
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXCalendarService, providedIn: 'root' }); }
|
|
1131
|
+
}
|
|
1132
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXCalendarService, decorators: [{
|
|
1133
|
+
type: Injectable,
|
|
1134
|
+
args: [{ providedIn: 'root' }]
|
|
1135
|
+
}], ctorParameters: () => [] });
|
|
1136
|
+
|
|
1137
|
+
class AXDateTimeFormatter {
|
|
1138
|
+
constructor() {
|
|
1139
|
+
this.calendarService = inject(AXCalendarService);
|
|
1140
|
+
}
|
|
1141
|
+
get name() {
|
|
1142
|
+
return 'datetime';
|
|
1143
|
+
}
|
|
1144
|
+
format(value, options) {
|
|
1145
|
+
const effectiveOptions = typeof options == 'object'
|
|
1146
|
+
? {
|
|
1147
|
+
format: options.format ?? 'date',
|
|
1148
|
+
locale: options.locale,
|
|
1149
|
+
calendar: options.calendar ?? this.calendarService.calendar.name(),
|
|
1150
|
+
}
|
|
1151
|
+
: {
|
|
1152
|
+
format: options,
|
|
1153
|
+
calendar: this.calendarService.calendar.name(),
|
|
1154
|
+
};
|
|
1155
|
+
return this.calendarService
|
|
1156
|
+
.create(value, effectiveOptions.calendar)
|
|
1157
|
+
.format(effectiveOptions.format, { locale: effectiveOptions.locale });
|
|
1158
|
+
}
|
|
1159
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimeFormatter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1160
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimeFormatter }); }
|
|
1161
|
+
}
|
|
1162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimeFormatter, decorators: [{
|
|
1163
|
+
type: Injectable
|
|
1164
|
+
}] });
|
|
1165
|
+
|
|
1166
|
+
class AXTimeLeftFormatter {
|
|
1167
|
+
get name() {
|
|
1168
|
+
return 'timeleft';
|
|
1169
|
+
}
|
|
1170
|
+
format(value, options) {
|
|
1171
|
+
const milliseconds = Number(value);
|
|
1172
|
+
if (milliseconds === null || isNaN(milliseconds)) {
|
|
1173
|
+
return 'Calculating...';
|
|
1174
|
+
}
|
|
1175
|
+
const durationInSeconds = Math.round(milliseconds / 1000);
|
|
1176
|
+
let format = options?.format;
|
|
1177
|
+
// Determine the best format if format is null
|
|
1178
|
+
if (isNil(format)) {
|
|
1179
|
+
if (durationInSeconds < 45)
|
|
1180
|
+
format = 's';
|
|
1181
|
+
else if (durationInSeconds < 60 * 45)
|
|
1182
|
+
format = 'm';
|
|
1183
|
+
else if (durationInSeconds < 60 * 60 * 22)
|
|
1184
|
+
format = 'h';
|
|
1185
|
+
else if (durationInSeconds < 60 * 60 * 24 * 26)
|
|
1186
|
+
format = 'd';
|
|
1187
|
+
else if (durationInSeconds < 60 * 60 * 24 * 320)
|
|
1188
|
+
format = 'M';
|
|
1189
|
+
else
|
|
1190
|
+
format = 'y';
|
|
1191
|
+
}
|
|
1192
|
+
// Helper function for zero-padding
|
|
1193
|
+
const pad = (num) => num.toString().padStart(2, '0');
|
|
1194
|
+
switch (format) {
|
|
1195
|
+
case 's':
|
|
1196
|
+
return `${durationInSeconds} seconds left`;
|
|
1197
|
+
case 'ss':
|
|
1198
|
+
return `${pad(durationInSeconds)} seconds left`;
|
|
1199
|
+
case 'm':
|
|
1200
|
+
return `${Math.round(durationInSeconds / 60)} minute${durationInSeconds >= 120 ? 's' : ''} left`;
|
|
1201
|
+
case 'mm':
|
|
1202
|
+
return `${pad(Math.round(durationInSeconds / 60))} minutes left`;
|
|
1203
|
+
case 'h':
|
|
1204
|
+
case 'H':
|
|
1205
|
+
if (durationInSeconds < 60 * 89)
|
|
1206
|
+
return 'an hour left';
|
|
1207
|
+
return `${Math.round(durationInSeconds / 3600)} hour${durationInSeconds >= 60 * 180 ? 's' : ''} left`;
|
|
1208
|
+
case 'hh':
|
|
1209
|
+
case 'HH':
|
|
1210
|
+
if (durationInSeconds < 60 * 89)
|
|
1211
|
+
return '01 hour left';
|
|
1212
|
+
return `${pad(Math.round(durationInSeconds / 3600))} hours left`;
|
|
1213
|
+
case 'd':
|
|
1214
|
+
case 'D':
|
|
1215
|
+
if (durationInSeconds < 60 * 60 * 35)
|
|
1216
|
+
return 'a day left';
|
|
1217
|
+
return `${Math.round(durationInSeconds / (3600 * 24))} day${durationInSeconds >= 60 * 60 * 70 ? 's' : ''} left`;
|
|
1218
|
+
case 'dd':
|
|
1219
|
+
case 'DD':
|
|
1220
|
+
if (durationInSeconds < 60 * 60 * 35)
|
|
1221
|
+
return '01 day left';
|
|
1222
|
+
return `${pad(Math.round(durationInSeconds / (3600 * 24)))} days left`;
|
|
1223
|
+
case 'M':
|
|
1224
|
+
if (durationInSeconds < 60 * 60 * 24 * 45)
|
|
1225
|
+
return 'a month left';
|
|
1226
|
+
return `${Math.round(durationInSeconds / (3600 * 24 * 30))} month${durationInSeconds >= 60 * 60 * 24 * 90 ? 's' : ''} left`;
|
|
1227
|
+
case 'MM':
|
|
1228
|
+
if (durationInSeconds < 60 * 60 * 24 * 45)
|
|
1229
|
+
return '01 month left';
|
|
1230
|
+
return `${pad(Math.round(durationInSeconds / (3600 * 24 * 30)))} months left`;
|
|
1231
|
+
case 'y':
|
|
1232
|
+
case 'Y':
|
|
1233
|
+
if (durationInSeconds < 60 * 60 * 24 * 547)
|
|
1234
|
+
return 'a year left';
|
|
1235
|
+
return `${Math.round(durationInSeconds / (3600 * 24 * 365))} year${durationInSeconds >= 60 * 60 * 24 * 730 ? 's' : ''} left`;
|
|
1236
|
+
case 'yy':
|
|
1237
|
+
case 'YY':
|
|
1238
|
+
case 'yyyy':
|
|
1239
|
+
case 'YYYY':
|
|
1240
|
+
if (durationInSeconds < 60 * 60 * 24 * 547)
|
|
1241
|
+
return '01 year left';
|
|
1242
|
+
return `${pad(Math.round(durationInSeconds / (3600 * 24 * 365)))} years left`;
|
|
1243
|
+
default:
|
|
1244
|
+
return 'Invalid format';
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXTimeLeftFormatter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1248
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXTimeLeftFormatter }); }
|
|
1249
|
+
}
|
|
1250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXTimeLeftFormatter, decorators: [{
|
|
1251
|
+
type: Injectable
|
|
1252
|
+
}] });
|
|
1253
|
+
|
|
1254
|
+
/**
|
|
1255
|
+
* @deprecated The pipe should not be used, use format instead
|
|
1256
|
+
*/
|
|
1257
|
+
class AXDateTimePipe {
|
|
1258
|
+
constructor() {
|
|
1259
|
+
this._calendarService = inject(AXCalendarService);
|
|
1260
|
+
}
|
|
1261
|
+
transform(value, format, calendarName) {
|
|
1262
|
+
if (value == null) {
|
|
1263
|
+
return '';
|
|
1264
|
+
}
|
|
1265
|
+
let calendar = this._calendarService.calendar;
|
|
1266
|
+
if (calendarName) {
|
|
1267
|
+
calendar = this._calendarService.resolveCalendar(calendarName);
|
|
1268
|
+
}
|
|
1269
|
+
const val = this._calendarService.convert(value, calendar.name());
|
|
1270
|
+
return val.format(format);
|
|
1271
|
+
}
|
|
1272
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1273
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimePipe, name: "axDate" }); }
|
|
1274
|
+
}
|
|
1275
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimePipe, decorators: [{
|
|
1276
|
+
type: Pipe,
|
|
1277
|
+
args: [{ name: 'axDate' }]
|
|
1278
|
+
}] });
|
|
1279
|
+
|
|
1280
|
+
class AXDateTimeModule {
|
|
1281
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1282
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimeModule, declarations: [AXDateTimePipe], imports: [i1.AXFormatModule], exports: [AXDateTimePipe] }); }
|
|
1283
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimeModule, imports: [AXFormatModule.forChild({
|
|
1284
|
+
formatters: [AXDateTimeFormatter, AXTimeLeftFormatter],
|
|
1285
|
+
})] }); }
|
|
1286
|
+
}
|
|
1287
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXDateTimeModule, decorators: [{
|
|
1288
|
+
type: NgModule,
|
|
1289
|
+
args: [{
|
|
1290
|
+
imports: [
|
|
1291
|
+
AXFormatModule.forChild({
|
|
1292
|
+
formatters: [AXDateTimeFormatter, AXTimeLeftFormatter],
|
|
1293
|
+
}),
|
|
1294
|
+
],
|
|
1295
|
+
exports: [AXDateTimePipe],
|
|
1296
|
+
declarations: [AXDateTimePipe],
|
|
1297
|
+
}]
|
|
1298
|
+
}] });
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* Generated bundle index. Do not edit.
|
|
1302
|
+
*/
|
|
1303
|
+
|
|
1304
|
+
export { AXCalendar, AXCalendarMonth, AXCalendarService, AXDateTime, AXDateTimeDefaultConfig, AXDateTimeFormatter, AXDateTimeModule, AXDateTimePipe, AXDateTimeRange, AXHolidaysLoaderDefault, AXTimeLeftFormatter, AX_DATETIME_CONFIG, AX_DATETIME_HOLIDAYS_LOADER, GeorgianCalendar, JalaliCalendar, dateTimeConfig };
|
|
1305
|
+
//# sourceMappingURL=acorex-core-date-time.mjs.map
|