@timestamp-js/calendar-islamic 0.1.0-rc.1 → 0.1.0-rc.2
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/README.md +17 -0
- package/dist/index.global.js +269 -0
- package/dist/index.global.min.js +1 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -42,5 +42,22 @@ monthEnd.date // '1445-09-30'
|
|
|
42
42
|
monthDays.length // 30
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
## Browser Globals
|
|
46
|
+
|
|
47
|
+
For CDN or CodePen usage, load `@timestamp-js/core` before the adapter package:
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<script src="https://cdn.jsdelivr.net/npm/@timestamp-js/core@0.1.0-rc.2/dist/index.global.min.js"></script>
|
|
51
|
+
<script src="https://cdn.jsdelivr.net/npm/@timestamp-js/calendar-islamic@0.1.0-rc.2/dist/index.global.min.js"></script>
|
|
52
|
+
<script>
|
|
53
|
+
const visible = TimestampJsCore.parseCalendarTimestamp(
|
|
54
|
+
'1445-09-15',
|
|
55
|
+
TimestampJsCalendarIslamic.islamicCivilCalendar,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
console.log(visible?.calendarId)
|
|
59
|
+
</script>
|
|
60
|
+
```
|
|
61
|
+
|
|
45
62
|
This package is early calendar-adapter work. Treat the adapter contract as release-candidate API
|
|
46
63
|
until `@timestamp-js/core` reaches a stable `1.0.0`.
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
var TimestampJsCalendarIslamic = (function(exports) {
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
|
|
5
|
+
const MILLISECONDS_IN_DAY$1 = 864e5;
|
|
6
|
+
const GREGORIAN_DAYS_IN_MONTH = [
|
|
7
|
+
0,
|
|
8
|
+
31,
|
|
9
|
+
28,
|
|
10
|
+
31,
|
|
11
|
+
30,
|
|
12
|
+
31,
|
|
13
|
+
30,
|
|
14
|
+
31,
|
|
15
|
+
31,
|
|
16
|
+
30,
|
|
17
|
+
31,
|
|
18
|
+
30,
|
|
19
|
+
31
|
|
20
|
+
];
|
|
21
|
+
const GREGORIAN_DAYS_IN_MONTH_LEAP = [
|
|
22
|
+
0,
|
|
23
|
+
31,
|
|
24
|
+
29,
|
|
25
|
+
31,
|
|
26
|
+
30,
|
|
27
|
+
31,
|
|
28
|
+
30,
|
|
29
|
+
31,
|
|
30
|
+
31,
|
|
31
|
+
30,
|
|
32
|
+
31,
|
|
33
|
+
30,
|
|
34
|
+
31
|
|
35
|
+
];
|
|
36
|
+
function fromUtcDate(date) {
|
|
37
|
+
return {
|
|
38
|
+
year: date.getUTCFullYear(),
|
|
39
|
+
month: date.getUTCMonth() + 1,
|
|
40
|
+
day: date.getUTCDate()
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function toGregorianUtcDate(date) {
|
|
44
|
+
return new Date(Date.UTC(date.year, date.month - 1, date.day));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const gregorianCalendar = Object.freeze({
|
|
48
|
+
id: "gregorian",
|
|
49
|
+
intlCalendar: "gregory",
|
|
50
|
+
label: "Gregorian",
|
|
51
|
+
monthsInYear() {
|
|
52
|
+
return 12;
|
|
53
|
+
},
|
|
54
|
+
isLeapYear(year) {
|
|
55
|
+
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
|
|
56
|
+
},
|
|
57
|
+
daysInMonth(year, month) {
|
|
58
|
+
return this.isLeapYear(year) ? GREGORIAN_DAYS_IN_MONTH_LEAP[month] : GREGORIAN_DAYS_IN_MONTH[month];
|
|
59
|
+
},
|
|
60
|
+
toEpochDay(date) {
|
|
61
|
+
return Math.floor(Date.UTC(date.year, date.month - 1, date.day) / MILLISECONDS_IN_DAY$1);
|
|
62
|
+
},
|
|
63
|
+
fromEpochDay(epochDay) {
|
|
64
|
+
return fromUtcDate(/* @__PURE__ */ new Date(epochDay * MILLISECONDS_IN_DAY$1));
|
|
65
|
+
},
|
|
66
|
+
addDays(date, amount) {
|
|
67
|
+
return this.fromEpochDay(this.toEpochDay(date) + amount);
|
|
68
|
+
},
|
|
69
|
+
nextDay(date) {
|
|
70
|
+
return this.addDays(date, 1);
|
|
71
|
+
},
|
|
72
|
+
prevDay(date) {
|
|
73
|
+
return this.addDays(date, -1);
|
|
74
|
+
},
|
|
75
|
+
getDayOfYear(date) {
|
|
76
|
+
const yearStart = this.toEpochDay({
|
|
77
|
+
year: date.year,
|
|
78
|
+
month: 1,
|
|
79
|
+
day: 1
|
|
80
|
+
});
|
|
81
|
+
return this.toEpochDay(date) - yearStart + 1;
|
|
82
|
+
},
|
|
83
|
+
getWeekday(date) {
|
|
84
|
+
return toGregorianUtcDate(date).getUTCDay();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
const TIME_CONSTANTS = {
|
|
90
|
+
MILLISECONDS_IN: {
|
|
91
|
+
SECOND: 1e3,
|
|
92
|
+
MINUTE: 6e4,
|
|
93
|
+
HOUR: 36e5,
|
|
94
|
+
DAY: 864e5,
|
|
95
|
+
WEEK: 6048e5
|
|
96
|
+
},
|
|
97
|
+
SECONDS_IN: {
|
|
98
|
+
MINUTE: 60,
|
|
99
|
+
HOUR: 3600,
|
|
100
|
+
DAY: 86400,
|
|
101
|
+
WEEK: 604800
|
|
102
|
+
},
|
|
103
|
+
MINUTES_IN: {
|
|
104
|
+
MINUTE: 1,
|
|
105
|
+
HOUR: 60,
|
|
106
|
+
DAY: 1440,
|
|
107
|
+
WEEK: 10080
|
|
108
|
+
},
|
|
109
|
+
HOURS_IN: {
|
|
110
|
+
DAY: 24,
|
|
111
|
+
WEEK: 168
|
|
112
|
+
},
|
|
113
|
+
DAYS_IN: { WEEK: 7 }
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const DAYS_IN_WEEK = TIME_CONSTANTS.DAYS_IN.WEEK;
|
|
117
|
+
|
|
118
|
+
const MINUTES_IN_HOUR = TIME_CONSTANTS.MINUTES_IN.HOUR;
|
|
119
|
+
|
|
120
|
+
const HOURS_IN_DAY = TIME_CONSTANTS.HOURS_IN.DAY;
|
|
121
|
+
|
|
122
|
+
const MILLISECONDS_IN_MINUTE = TIME_CONSTANTS.MILLISECONDS_IN.MINUTE;
|
|
123
|
+
|
|
124
|
+
const MILLISECONDS_IN_SECOND = TIME_CONSTANTS.MILLISECONDS_IN.SECOND;
|
|
125
|
+
|
|
126
|
+
const MILLISECONDS_IN_HOUR = TIME_CONSTANTS.MILLISECONDS_IN.HOUR;
|
|
127
|
+
|
|
128
|
+
const MILLISECONDS_IN_DAY = TIME_CONSTANTS.MILLISECONDS_IN.DAY;
|
|
129
|
+
|
|
130
|
+
const MILLISECONDS_IN_WEEK = TIME_CONSTANTS.MILLISECONDS_IN.WEEK;
|
|
131
|
+
|
|
132
|
+
const SECONDS_IN_MINUTE = TIME_CONSTANTS.SECONDS_IN.MINUTE;
|
|
133
|
+
|
|
134
|
+
const SECONDS_IN_HOUR = TIME_CONSTANTS.SECONDS_IN.HOUR;
|
|
135
|
+
|
|
136
|
+
const SECONDS_IN_DAY = TIME_CONSTANTS.SECONDS_IN.DAY;
|
|
137
|
+
|
|
138
|
+
const Timestamp = freezeTimestamp({
|
|
139
|
+
date: "",
|
|
140
|
+
hasDay: false,
|
|
141
|
+
year: 0,
|
|
142
|
+
month: 0,
|
|
143
|
+
day: 0,
|
|
144
|
+
hasTime: false,
|
|
145
|
+
hour: 0,
|
|
146
|
+
minute: 0,
|
|
147
|
+
weekday: 0,
|
|
148
|
+
doy: 0,
|
|
149
|
+
workweek: 0,
|
|
150
|
+
past: false,
|
|
151
|
+
current: false,
|
|
152
|
+
future: false,
|
|
153
|
+
disabled: false
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const TimeObject = Object.freeze({
|
|
157
|
+
hour: 0,
|
|
158
|
+
minute: 0
|
|
159
|
+
});
|
|
160
|
+
function freezeTimestamp(timestamp) {
|
|
161
|
+
return Object.freeze({ ...timestamp });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const ISLAMIC_EPOCH_DAY = gregorianCalendar.toEpochDay({
|
|
165
|
+
year: 622,
|
|
166
|
+
month: 7,
|
|
167
|
+
day: 19
|
|
168
|
+
});
|
|
169
|
+
const MONTHS_IN_YEAR = 12;
|
|
170
|
+
function assertPositiveYear(year) {
|
|
171
|
+
if (year < 1) throw new RangeError("Islamic calendar years start at 1 AH.");
|
|
172
|
+
}
|
|
173
|
+
function daysBeforeYear(year) {
|
|
174
|
+
assertPositiveYear(year);
|
|
175
|
+
return (year - 1) * 354 + Math.floor((3 + 11 * year) / 30);
|
|
176
|
+
}
|
|
177
|
+
function daysBeforeMonth(month) {
|
|
178
|
+
return Math.ceil(29.5 * (month - 1));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function isIslamicCivilLeapYear(year) {
|
|
182
|
+
assertPositiveYear(year);
|
|
183
|
+
return (11 * year + 14) % 30 < 11;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function islamicCivilDaysInMonth(year, month) {
|
|
187
|
+
assertPositiveYear(year);
|
|
188
|
+
if (month < 1 || month > MONTHS_IN_YEAR) return 0;
|
|
189
|
+
if (month === 12 && isIslamicCivilLeapYear(year) === true) return 30;
|
|
190
|
+
return month % 2 === 1 ? 30 : 29;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const islamicCivilCalendar = Object.freeze({
|
|
194
|
+
id: "islamic-civil",
|
|
195
|
+
intlCalendar: "islamic-civil",
|
|
196
|
+
label: "Islamic Civil",
|
|
197
|
+
monthsInYear() {
|
|
198
|
+
return MONTHS_IN_YEAR;
|
|
199
|
+
},
|
|
200
|
+
isLeapYear(year) {
|
|
201
|
+
return isIslamicCivilLeapYear(year);
|
|
202
|
+
},
|
|
203
|
+
daysInMonth(year, month) {
|
|
204
|
+
return islamicCivilDaysInMonth(year, month);
|
|
205
|
+
},
|
|
206
|
+
toEpochDay(date) {
|
|
207
|
+
assertPositiveYear(date.year);
|
|
208
|
+
return ISLAMIC_EPOCH_DAY + daysBeforeYear(date.year) + daysBeforeMonth(date.month) + date.day - 1;
|
|
209
|
+
},
|
|
210
|
+
fromEpochDay(epochDay) {
|
|
211
|
+
const days = epochDay - ISLAMIC_EPOCH_DAY;
|
|
212
|
+
let year = Math.floor((30 * days + 10646) / 10631);
|
|
213
|
+
while (year > 1 && this.toEpochDay({
|
|
214
|
+
year,
|
|
215
|
+
month: 1,
|
|
216
|
+
day: 1
|
|
217
|
+
}) > epochDay) year -= 1;
|
|
218
|
+
while (this.toEpochDay({
|
|
219
|
+
year: year + 1,
|
|
220
|
+
month: 1,
|
|
221
|
+
day: 1
|
|
222
|
+
}) <= epochDay) year += 1;
|
|
223
|
+
let dayOfYear = epochDay - this.toEpochDay({
|
|
224
|
+
year,
|
|
225
|
+
month: 1,
|
|
226
|
+
day: 1
|
|
227
|
+
});
|
|
228
|
+
let month = 1;
|
|
229
|
+
while (month < MONTHS_IN_YEAR) {
|
|
230
|
+
const daysInCurrentMonth = this.daysInMonth(year, month);
|
|
231
|
+
if (dayOfYear < daysInCurrentMonth) break;
|
|
232
|
+
dayOfYear -= daysInCurrentMonth;
|
|
233
|
+
month += 1;
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
year,
|
|
237
|
+
month,
|
|
238
|
+
day: dayOfYear + 1
|
|
239
|
+
};
|
|
240
|
+
},
|
|
241
|
+
addDays(date, amount) {
|
|
242
|
+
return this.fromEpochDay(this.toEpochDay(date) + amount);
|
|
243
|
+
},
|
|
244
|
+
nextDay(date) {
|
|
245
|
+
return this.addDays(date, 1);
|
|
246
|
+
},
|
|
247
|
+
prevDay(date) {
|
|
248
|
+
return this.addDays(date, -1);
|
|
249
|
+
},
|
|
250
|
+
getDayOfYear(date) {
|
|
251
|
+
return this.toEpochDay(date) - this.toEpochDay({
|
|
252
|
+
year: date.year,
|
|
253
|
+
month: 1,
|
|
254
|
+
day: 1
|
|
255
|
+
}) + 1;
|
|
256
|
+
},
|
|
257
|
+
getWeekday(date) {
|
|
258
|
+
return gregorianCalendar.getWeekday(gregorianCalendar.fromEpochDay(this.toEpochDay(date)));
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const islamicCalendar = islamicCivilCalendar;
|
|
263
|
+
|
|
264
|
+
exports.isIslamicCivilLeapYear = isIslamicCivilLeapYear;
|
|
265
|
+
exports.islamicCalendar = islamicCalendar;
|
|
266
|
+
exports.islamicCivilCalendar = islamicCivilCalendar;
|
|
267
|
+
exports.islamicCivilDaysInMonth = islamicCivilDaysInMonth;
|
|
268
|
+
return exports;
|
|
269
|
+
})({});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var TimestampJsCalendarIslamic=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});let t=864e5,n=[0,31,28,31,30,31,30,31,31,30,31,30,31],r=[0,31,29,31,30,31,30,31,31,30,31,30,31];function i(e){return{year:e.getUTCFullYear(),month:e.getUTCMonth()+1,day:e.getUTCDate()}}function a(e){return new Date(Date.UTC(e.year,e.month-1,e.day))}let o=Object.freeze({id:`gregorian`,intlCalendar:`gregory`,label:`Gregorian`,monthsInYear(){return 12},isLeapYear(e){return e%4==0&&e%100!=0||e%400==0},daysInMonth(e,t){return this.isLeapYear(e)?r[t]:n[t]},toEpochDay(e){return Math.floor(Date.UTC(e.year,e.month-1,e.day)/t)},fromEpochDay(e){return i(new Date(e*t))},addDays(e,t){return this.fromEpochDay(this.toEpochDay(e)+t)},nextDay(e){return this.addDays(e,1)},prevDay(e){return this.addDays(e,-1)},getDayOfYear(e){let t=this.toEpochDay({year:e.year,month:1,day:1});return this.toEpochDay(e)-t+1},getWeekday(e){return a(e).getUTCDay()}}),s={MILLISECONDS_IN:{SECOND:1e3,MINUTE:6e4,HOUR:36e5,DAY:864e5,WEEK:6048e5},SECONDS_IN:{MINUTE:60,HOUR:3600,DAY:86400,WEEK:604800},MINUTES_IN:{MINUTE:1,HOUR:60,DAY:1440,WEEK:10080},HOURS_IN:{DAY:24,WEEK:168},DAYS_IN:{WEEK:7}};s.DAYS_IN.WEEK,s.MINUTES_IN.HOUR,s.HOURS_IN.DAY,s.MILLISECONDS_IN.MINUTE,s.MILLISECONDS_IN.SECOND,s.MILLISECONDS_IN.HOUR,s.MILLISECONDS_IN.DAY,s.MILLISECONDS_IN.WEEK,s.SECONDS_IN.MINUTE,s.SECONDS_IN.HOUR,s.SECONDS_IN.DAY,c({date:``,hasDay:!1,year:0,month:0,day:0,hasTime:!1,hour:0,minute:0,weekday:0,doy:0,workweek:0,past:!1,current:!1,future:!1,disabled:!1}),Object.freeze({hour:0,minute:0});function c(e){return Object.freeze({...e})}let l=o.toEpochDay({year:622,month:7,day:19});function u(e){if(e<1)throw RangeError(`Islamic calendar years start at 1 AH.`)}function d(e){return u(e),(e-1)*354+Math.floor((3+11*e)/30)}function f(e){return Math.ceil(29.5*(e-1))}function p(e){return u(e),(11*e+14)%30<11}function m(e,t){return u(e),t<1||t>12?0:t===12&&p(e)===!0||t%2==1?30:29}let h=Object.freeze({id:`islamic-civil`,intlCalendar:`islamic-civil`,label:`Islamic Civil`,monthsInYear(){return 12},isLeapYear(e){return p(e)},daysInMonth(e,t){return m(e,t)},toEpochDay(e){return u(e.year),l+d(e.year)+f(e.month)+e.day-1},fromEpochDay(e){let t=e-l,n=Math.floor((30*t+10646)/10631);for(;n>1&&this.toEpochDay({year:n,month:1,day:1})>e;)--n;for(;this.toEpochDay({year:n+1,month:1,day:1})<=e;)n+=1;let r=e-this.toEpochDay({year:n,month:1,day:1}),i=1;for(;i<12;){let e=this.daysInMonth(n,i);if(r<e)break;r-=e,i+=1}return{year:n,month:i,day:r+1}},addDays(e,t){return this.fromEpochDay(this.toEpochDay(e)+t)},nextDay(e){return this.addDays(e,1)},prevDay(e){return this.addDays(e,-1)},getDayOfYear(e){return this.toEpochDay(e)-this.toEpochDay({year:e.year,month:1,day:1})+1},getWeekday(e){return o.getWeekday(o.fromEpochDay(this.toEpochDay(e)))}}),g=h;return e.isIslamicCivilLeapYear=p,e.islamicCalendar=g,e.islamicCivilCalendar=h,e.islamicCivilDaysInMonth=m,e})({});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timestamp-js/calendar-islamic",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.2",
|
|
4
4
|
"description": "Islamic/Hijri calendar adapters for Timestamp.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"calendar",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"sideEffects": false,
|
|
30
30
|
"main": "./dist/index.js",
|
|
31
31
|
"types": "./dist/index.d.ts",
|
|
32
|
+
"unpkg": "./dist/index.global.min.js",
|
|
33
|
+
"jsdelivr": "./dist/index.global.min.js",
|
|
32
34
|
"exports": {
|
|
33
35
|
".": {
|
|
34
36
|
"types": "./dist/index.d.ts",
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
"access": "public"
|
|
40
42
|
},
|
|
41
43
|
"dependencies": {
|
|
42
|
-
"@timestamp-js/core": "0.1.0-rc.
|
|
44
|
+
"@timestamp-js/core": "0.1.0-rc.2"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
|
45
47
|
"@types/node": "26.0.1",
|
|
@@ -55,7 +57,7 @@
|
|
|
55
57
|
"scripts": {
|
|
56
58
|
"clean": "rm -rf dist node_modules",
|
|
57
59
|
"prebuild": "pnpm --filter @timestamp-js/core build",
|
|
58
|
-
"build": "tsc -p tsconfig.build.json",
|
|
60
|
+
"build": "node ../../scripts/build-browser-globals.mjs @timestamp-js/calendar-islamic && tsc -p tsconfig.build.json",
|
|
59
61
|
"format": "oxfmt",
|
|
60
62
|
"format:check": "oxfmt --check",
|
|
61
63
|
"lint": "oxlint",
|