arabic-datetime 1.0.0

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 ADDED
@@ -0,0 +1,263 @@
1
+
2
+ # arabic-datetime
3
+
4
+ _Author_: Khaldevmedia
5
+
6
+ _Description_: A Node package that helps you output dates in Arabic as strings, with formatting specific to each Arab country.
7
+
8
+ _Version_: 1.0.0
9
+ > **Note**: This Node package was created after the success of our [arabic-datetime](https://pypi.org/project/arabic-datetime/) Python package.
10
+
11
+ ## Using The Package for Date Formatting
12
+
13
+ This Node package is designed to simplify Arabic date formatting in your project by providing easy-to-use date formatting functions.
14
+ It can be used to simplify your frontend or backend operations. Instead of installing a full internationalisation package, you can use this package to display Arabic dates formatted according to local settings, whether the response content type is HTML or JSON. It's lightweight, efficient and easy to integrate into your existing project. By using this package, you can keep your backend lean and focused, while still providing a localised user experience.
15
+
16
+ ## Month names in Arabic
17
+
18
+ There are **5 groups** of month names in Arabic.
19
+
20
+ ### Syriac names:
21
+
22
+ The **Syriac** names of months are used in Syria, Palestine Lebanon, Iraq and Jordan:
23
+
24
+ > <p dir="rtl">كانون الثاني، شباط، آذار، نيسان، أيار، حزيران، تموز، آب، أيلول، تشرين الأول، تشرين الثاني، كانون الأول.</p>
25
+
26
+ ### Roman names (group 1):
27
+
28
+ The **Roman names (group 1)** of months are used in Egypt, Yemen, Sudan, Libya, Djibouti, Comoro, Somalia, Saudi Arabia, United Arab Emirates, Qatar, Oman, Bahrain and Kuwait:
29
+
30
+ > <p dir="rtl">يناير، فبراير، مارس، أبريل، مايو، يونيو، يوليو، أغسطس، سبتمبر، أكتوبر، نوفمبر، ديسمبر.</p>
31
+
32
+ ### Roman names (group 2):
33
+
34
+ The **Roman names (group 2)** of months are used in Morocco:
35
+
36
+ > <p dir="rtl">يناير، فبراير، مارس، أبريل، ماي، يونيو، يوليوز، غشت، شتنبر، أكتوبر، نونبر، دجنبر.</p>
37
+
38
+ ### Roman names (group 3):
39
+
40
+ The **Roman names (group 3)** of months are used in Mauritania:
41
+
42
+ > <p dir="rtl">يناير، فبراير، مارس، إبريل، مايو، يونيو، يوليو، أغشت، شتمبر، أكتوبر، نوفمبر، ديسمبر.</p>
43
+
44
+ ### French names:
45
+
46
+ The **French** names of months are used in Algeria and Tunisia:
47
+
48
+ > <p dir="rtl">جانفي، فيفري، مارس، أفريل، ماي، جوان، جويلية، أوت، سبتمبر، أكتوبر، نوفمبر، ديسمبر.</p>
49
+
50
+ ## Arabic Numerals
51
+
52
+ There are two groups of **Arabic numerals** used in the Arab countries.
53
+
54
+ ### Eastern Arabic Numerals
55
+
56
+ They are used in all Arab countries except Algeria, Tunisia, Morocco and Mauritania:
57
+
58
+ > ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩
59
+
60
+ ### Western Arabic Numerals
61
+
62
+ They are mainly used in Algeria, Tunisia, Morocco and Mauritania. However, they are also used in the other Arab countries that use the eastern Arabic numerals:
63
+
64
+ > 0 1 2 3 4 5 6 7 8 9
65
+
66
+ ### Numerals Options
67
+
68
+ You can use the eastern or the western Arabic numerals regardless of the month names group you use. As demonstrated below, there is always a default numerals' type depending on the method used.
69
+
70
+ ## Installation
71
+
72
+ ```bash
73
+ npm install arabic-datetime
74
+ ```
75
+
76
+ ## Examples
77
+
78
+ ### 1. Date
79
+
80
+ The `ArabicDate` class has several methods that return an Arabic date as a string.
81
+
82
+ #### A specific method for every month names group
83
+
84
+ ```ts
85
+ import { ArabicDate } from 'arabic-datetime';
86
+
87
+ // Create arabicDate object from a JavaScript Date instance
88
+ const jsDate: Date = new Date(1980, 7, 16); // Months are 0-based, so 7 represents August
89
+ const arabicDate: ArabicDate = new ArabicDate(jsDate);
90
+
91
+ // Use each method to create the Arabic date strings
92
+ const syriacDateFormat: string = arabicDate.syriacNames();
93
+ const egyptDateFormat: string = arabicDate.roman1Names();
94
+ const moroccoDateFormat: string = arabicDate.roman2Names();
95
+ const algeriaDateFormat: string = arabicDate.frenchNames();
96
+
97
+ console.log(syriacDateFormat); // output 16 آب 1980
98
+ console.log(egyptDateFormat); // output 16 أغسطس 1980
99
+ console.log(moroccoDateFormat); // output 16 غشت 1980
100
+ console.log(algeriaDateFormat); // output 16 أوت 1980
101
+
102
+ // To use Eastern Arabic Numerals pass true to the method you use
103
+ const syriacDateFormatEastern: string = arabicDate.syriacNames(true);
104
+ console.log(syriacDateFormatEastern); // output ١٦ آب ١٩٨٠
105
+ ```
106
+
107
+ > ##### Note:
108
+ >
109
+ > When you combine Western Arabic numerals or western punctuations with Arabic characters they appear messed up if the text direction in the target is set to `left to right` or `dir=ltr` in `HTML`.
110
+ >
111
+ > In order for the Arabic date to appear properly, especially if it uses western Arabic numerals, the direction of the text in the interface you are using must be `right to left`. If you insert the date into an `HTML` element set text direction to `rtl`. If the text direction in the whole `HTML` document is set to `rtl` you should be OK.
112
+
113
+ ```html
114
+ <p dir="rtl">16 آب 1980</p>
115
+ <p dir="rtl">16 أوت 1980</p>
116
+ ```
117
+
118
+ > The result will look like this:
119
+ >
120
+ > <p dir="rtl">16 آب 1980</p>
121
+ > <p dir="rtl">16 أوت 1980</p>
122
+
123
+ #### A dual date name method
124
+
125
+ It's very common that two month names are used at the same time to display the date in Arabic with the second one put between parentheses, like this:
126
+
127
+ > <p dir="rtl">16 آب (أغسطس) 1980</p>
128
+ > <p dir="rtl">١٦ آب (أغسطس) ١٩٨٠</p>
129
+
130
+ To get the Arabic date formatted like this, use the `dualNames` method:
131
+
132
+ ```ts
133
+ import { ArabicDate } from 'arabic-datetime';
134
+
135
+ // Create arabicDate object from a JavaScript Date instance
136
+ const jsDate: Date = new Date(1980, 7, 16);
137
+ const arabicDate: ArabicDate = new ArabicDate(jsDate);
138
+
139
+ // Use the dualNames() method to return an Arabic date string that shows two names of the month.
140
+ // This method takes 3 arguments: 2 strings for the month group names (the second one
141
+ // will be put between parentheses), and a boolean to determine whether to format the
142
+ // Arabic date with the Eastern Numerals or not:
143
+ const dualDateRoSy: string = arabicDate.dualNames('syriac', 'roman1', false);
144
+ console.log(dualDateRoSy); // output 16 أغسطس (آب) 1980
145
+
146
+ // If you don't pass the third argument, the default is false. Also you can use
147
+ // named arguments if you're in TypeScript by passing an options object to clarify intent.
148
+
149
+ // To use Eastern Arabic Numerals, pass true as the third argument.
150
+ // We will also switch the month names in this example:
151
+ const dualDateSyRo: string = arabicDate.dualNames('syriac', 'roman1', true);
152
+ console.log(dualDateSyRo); // output ١٦ آب (أغسطس) ١٩٨٠
153
+ ```
154
+
155
+ ##### Accepted values for group names (Look above to see which Arab country uses which names):
156
+
157
+ ```
158
+ "syriac" : For Syriac names
159
+ "roman1" : For Roman names (group 1)
160
+ "roman2" : For Roman names (group 2)
161
+ "french" : For French names
162
+ ```
163
+
164
+ #### A method that takes a country code to return the corresponding date format
165
+
166
+ ```ts
167
+ import { ArabicDate } from 'arabic-datetime';
168
+
169
+ // Create arabicDate object from a JavaScript Date instance
170
+ const jsDate: Date = new Date(1980, 7, 16);
171
+ const arabicDate: ArabicDate = new ArabicDate(jsDate);
172
+
173
+ // Use of byCountryCode() method. It takes countryCode as a string
174
+ // If you don't pass true or false besides the country code string
175
+ // the method will return the numeral type that is most common in that country
176
+ const syriacDateFormat: string = arabicDate.byCountryCode('SY');
177
+ const algeriaDateFormat: string = arabicDate.byCountryCode('DZ');
178
+ console.log(syriacDateFormat); // output ١٦ آب ١٩٨٠
179
+ console.log(algeriaDateFormat); // output 16 أوت 1980
180
+
181
+ // But if you want to force the numeral type, pass as a second argument
182
+ // true for eastern numerals and false for western numerals
183
+ const syriacDateFormatWestern: string = arabicDate.byCountryCode('SY', false);
184
+ const algeriaDateFormatEastern: string = arabicDate.byCountryCode('DZ', true);
185
+ console.log(syriacDateFormatWestern); // output 16 آب 1980
186
+ console.log(algeriaDateFormatEastern); // output ١٦ أوت ١٩٨٠
187
+ ```
188
+
189
+ ##### List of country codes:
190
+
191
+ ```
192
+ DZ: Algeria
193
+ BH: Bahrain
194
+ KM: Comoros
195
+ DJ: Djibouti
196
+ EG: Egypt
197
+ IQ: Iraq
198
+ JO: Jordan
199
+ KW: Kuwait
200
+ LB: Lebanon
201
+ LY: Libya
202
+ MR: Mauritania
203
+ MA: Morocco
204
+ OM: Oman
205
+ PS: Palestine
206
+ QA: Qatar
207
+ SA: Saudi Arabia
208
+ SO: Somalia
209
+ SD: Sudan
210
+ SY: Syria
211
+ TN: Tunisia
212
+ AE: United Arab Emirates
213
+ YE: Yemen
214
+ ```
215
+
216
+ ### 2. Time
217
+
218
+ The `ArabicTime` class has one method that returns Arabic time as a string using the Eastern Arabic numerals. It takes two parameters: `format` with default value as `"HMS"` and `separator` with default value as `":"`.
219
+
220
+ ```ts
221
+ import { ArabicTime } from 'arabic-datetime';
222
+
223
+ const jsDate: Date = new Date(1980, 7, 16, 12, 30, 45, 123);
224
+ const arabicTime: ArabicTime = new ArabicTime(jsDate);
225
+ const hmsTime: string = arabicTime.time('HMS');
226
+ const hmTime: string = arabicTime.time('HM');
227
+ const hmSlashTime: string = arabicTime.time('HM', '/');
228
+ console.log(hmsTime); // output ١٢:٣٠:٤٥
229
+ console.log(hmTime); // output ١٢:٣٠
230
+ console.log(hmSlashTime); // output ١٢/٣٠
231
+ ```
232
+
233
+ ##### Valid `format` values:
234
+
235
+ ```
236
+ "H": Shows hour only.
237
+ "HM": Shows hour and minute.
238
+ "HMS": Shows hour, minute and second.
239
+ "HMSF": Shows hour, minute, second and millisecond.
240
+ ```
241
+
242
+ > #### Note:
243
+ >
244
+ > As explained above, make sure that the direction of the text in which the Arabic time is inserted is `right to left`.
245
+
246
+ ```html
247
+ <p dir="rtl">١٢:٣٠:٤٥</p>
248
+ <p dir="rtl">الساعة حالياً: ١٢:٣٠:٤٥</p>
249
+ ```
250
+
251
+ > The result will look like this:
252
+ >
253
+ > <p dir="rtl">١٢:٣٠:٤٥</p>
254
+ > <p dir="rtl">الساعة حالياً: ١٢:٣٠:٤٥</p>
255
+
256
+ ## License
257
+
258
+ GNU General Public License v3.0.
259
+
260
+ ## Contact
261
+
262
+ [www.khaldevmedia.com](https://www.khaldevmedia.com)
263
+
@@ -0,0 +1,354 @@
1
+ "use strict";
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
4
+ };
5
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
6
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
7
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
8
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
9
+ var _date, _year, _monthIndex, _day, _time, _hour, _minute, _second, _milliseconds;
10
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
11
+ const AR_NUMS = {
12
+ "0": "٠",
13
+ "1": "١",
14
+ "2": "٢",
15
+ "3": "٣",
16
+ "4": "٤",
17
+ "5": "٥",
18
+ "6": "٦",
19
+ "7": "٧",
20
+ "8": "٨",
21
+ "9": "٩"
22
+ };
23
+ const MONTH_GROUP_NAMES = [
24
+ "syriac",
25
+ "roman1",
26
+ "roman2",
27
+ "roman3",
28
+ "french"
29
+ ];
30
+ const COUNTRY_CODES = [
31
+ "IQ",
32
+ "JO",
33
+ "LB",
34
+ "PS",
35
+ "SO",
36
+ "SY",
37
+ "BH",
38
+ "KM",
39
+ "DJ",
40
+ "EG",
41
+ "KW",
42
+ "LY",
43
+ "OM",
44
+ "QA",
45
+ "SA",
46
+ "SD",
47
+ "AE",
48
+ "YE",
49
+ "MA",
50
+ "MR",
51
+ "DZ",
52
+ "TN"
53
+ ];
54
+ const isCountryCode = (value) => COUNTRY_CODES.includes(value);
55
+ const MONTH_GROUPS = {
56
+ syriac: {
57
+ eastNums: true,
58
+ months: [
59
+ "كانون الثاني",
60
+ "شباط",
61
+ "آذار",
62
+ "نيسان",
63
+ "أيار",
64
+ "حزيران",
65
+ "تموز",
66
+ "آب",
67
+ "أيلول",
68
+ "تشرين الأول",
69
+ "تشرين الثاني",
70
+ "كانون الأول"
71
+ ],
72
+ countries: ["IQ", "JO", "LB", "PS", "SY"]
73
+ },
74
+ roman1: {
75
+ eastNums: true,
76
+ months: [
77
+ "يناير",
78
+ "فبراير",
79
+ "مارس",
80
+ "أبريل",
81
+ "مايو",
82
+ "يونيو",
83
+ "يوليو",
84
+ "أغسطس",
85
+ "سبتمبر",
86
+ "أكتوبر",
87
+ "نوفمبر",
88
+ "ديسمبر"
89
+ ],
90
+ countries: ["BH", "KM", "DJ", "EG", "KW", "LY", "OM", "QA", "SA", "SO", "SD", "AE", "YE"]
91
+ },
92
+ roman2: {
93
+ eastNums: false,
94
+ months: [
95
+ "يناير",
96
+ "فبراير",
97
+ "مارس",
98
+ "أبريل",
99
+ "ماي",
100
+ "يونيو",
101
+ "يوليوز",
102
+ "غشت",
103
+ "شتنبر",
104
+ "أكتوبر",
105
+ "نونبر",
106
+ "دجنبر"
107
+ ],
108
+ countries: ["MA"]
109
+ },
110
+ roman3: {
111
+ eastNums: false,
112
+ months: [
113
+ "يناير",
114
+ "فبراير",
115
+ "مارس",
116
+ "إبريل",
117
+ "مايو",
118
+ "يونيو",
119
+ "يوليو",
120
+ "أغشت",
121
+ "شتمبر",
122
+ "أكتوبر",
123
+ "نوفمبر",
124
+ "ديسمبر"
125
+ ],
126
+ countries: ["MR"]
127
+ },
128
+ french: {
129
+ eastNums: false,
130
+ months: [
131
+ "جانفي",
132
+ "فيفري",
133
+ "مارس",
134
+ "أفريل",
135
+ "ماي",
136
+ "جوان",
137
+ "جويلية",
138
+ "أوت",
139
+ "سبتمبر",
140
+ "أكتوبر",
141
+ "نوفمبر",
142
+ "ديسمبر"
143
+ ],
144
+ countries: ["DZ", "TN"]
145
+ }
146
+ };
147
+ const WESTERN_DIGIT_PATTERN = /[0-9]/g;
148
+ const toArabicDigits = (value) => value.replace(WESTERN_DIGIT_PATTERN, (digit) => AR_NUMS[digit]);
149
+ const isValidDate = (value) => value instanceof Date && !Number.isNaN(value.valueOf());
150
+ class ArabicDate {
151
+ constructor(dateObject) {
152
+ __privateAdd(this, _date);
153
+ __privateAdd(this, _year);
154
+ __privateAdd(this, _monthIndex);
155
+ __privateAdd(this, _day);
156
+ this.setDate(dateObject);
157
+ }
158
+ get dateObject() {
159
+ return new Date(__privateGet(this, _date));
160
+ }
161
+ set dateObject(value) {
162
+ this.setDate(value);
163
+ }
164
+ syriacNames(eastNums = false) {
165
+ this.assertBoolean(eastNums, "syriacNames");
166
+ return this.composeGroupFormat("syriac", eastNums);
167
+ }
168
+ roman1Names(eastNums = false) {
169
+ this.assertBoolean(eastNums, "roman1Names");
170
+ return this.composeGroupFormat("roman1", eastNums);
171
+ }
172
+ roman2Names(eastNums = false) {
173
+ this.assertBoolean(eastNums, "roman2Names");
174
+ return this.composeGroupFormat("roman2", eastNums);
175
+ }
176
+ roman3Names(eastNums = false) {
177
+ this.assertBoolean(eastNums, "roman3Names");
178
+ return this.composeGroupFormat("roman3", eastNums);
179
+ }
180
+ frenchNames(eastNums = false) {
181
+ this.assertBoolean(eastNums, "frenchNames");
182
+ return this.composeGroupFormat("french", eastNums);
183
+ }
184
+ dualNames(first, second, eastNums = false) {
185
+ this.assertString(first, "first", "dualNames");
186
+ this.assertString(second, "second", "dualNames");
187
+ this.assertBoolean(eastNums, "dualNames");
188
+ const normalizedFirst = this.normalizeGroupName(first, "first", "dualNames");
189
+ const normalizedSecond = this.normalizeGroupName(second, "second", "dualNames");
190
+ if (normalizedFirst === normalizedSecond) {
191
+ throw new Error(
192
+ "ArabicDate class error: The first group name and the second group name should not be identical in the parameters passed to the method 'dualNames'."
193
+ );
194
+ }
195
+ const day = this.formatDay(eastNums);
196
+ const year = this.formatYear(eastNums);
197
+ const firstMonth = MONTH_GROUPS[normalizedFirst].months[__privateGet(this, _monthIndex)];
198
+ const secondMonth = MONTH_GROUPS[normalizedSecond].months[__privateGet(this, _monthIndex)];
199
+ return `${day} ${firstMonth} (${secondMonth}) ${year}`;
200
+ }
201
+ byCountryCode(countryCode, eastNums) {
202
+ this.assertString(countryCode, "country_code", "byCountryCode");
203
+ if (eastNums !== void 0) {
204
+ this.assertBoolean(eastNums, "byCountryCode");
205
+ }
206
+ const normalizedCode = countryCode.trim().toUpperCase();
207
+ if (!normalizedCode) {
208
+ throw new Error(
209
+ "ArabicDate class error: Unknown country code '' passed to the class method 'byCountryCode'."
210
+ );
211
+ }
212
+ if (!isCountryCode(normalizedCode)) {
213
+ throw new Error(
214
+ `ArabicDate class error: Unknown country code '${countryCode}' passed to the class method 'byCountryCode'.`
215
+ );
216
+ }
217
+ for (const groupName of MONTH_GROUP_NAMES) {
218
+ const group = MONTH_GROUPS[groupName];
219
+ if (group.countries.includes(normalizedCode)) {
220
+ const east = eastNums ?? group.eastNums;
221
+ return this.composeGroupFormat(groupName, east);
222
+ }
223
+ }
224
+ throw new Error(
225
+ `ArabicDate class error: Unknown country code '${countryCode}' passed to the class method 'byCountryCode'.`
226
+ );
227
+ }
228
+ easternNumericDate(separator = "/") {
229
+ this.assertString(separator, "separator", "easternNumericDate");
230
+ const month = (__privateGet(this, _monthIndex) + 1).toString();
231
+ return [__privateGet(this, _day), month, __privateGet(this, _year)].map(toArabicDigits).join(separator);
232
+ }
233
+ setDate(value) {
234
+ if (!isValidDate(value)) {
235
+ const message = value instanceof Date ? "ArabicDate class error: The parameter passed as dateObject is an invalid Date. Only valid Date objects are allowed." : "ArabicDate class error: The parameter passed as dateObject is not a Date. Only Date objects are allowed.";
236
+ throw new TypeError(message);
237
+ }
238
+ __privateSet(this, _date, new Date(value));
239
+ __privateSet(this, _year, __privateGet(this, _date).getFullYear().toString());
240
+ __privateSet(this, _monthIndex, __privateGet(this, _date).getMonth());
241
+ __privateSet(this, _day, __privateGet(this, _date).getDate().toString());
242
+ }
243
+ composeGroupFormat(groupName, eastNums) {
244
+ const day = this.formatDay(eastNums);
245
+ const month = MONTH_GROUPS[groupName].months[__privateGet(this, _monthIndex)];
246
+ const year = this.formatYear(eastNums);
247
+ return `${day} ${month} ${year}`;
248
+ }
249
+ formatDay(eastNums) {
250
+ return eastNums ? toArabicDigits(__privateGet(this, _day)) : __privateGet(this, _day);
251
+ }
252
+ formatYear(eastNums) {
253
+ return eastNums ? toArabicDigits(__privateGet(this, _year)) : __privateGet(this, _year);
254
+ }
255
+ assertBoolean(value, methodName) {
256
+ if (typeof value !== "boolean") {
257
+ throw new TypeError(
258
+ `ArabicDate class error: east_nums must be a boolean. '${String(value)}' is not a boolean and was passed to the class method '${methodName}'.`
259
+ );
260
+ }
261
+ }
262
+ assertString(value, parameterName, methodName) {
263
+ if (typeof value !== "string") {
264
+ throw new TypeError(
265
+ `ArabicDate class error: The '${parameterName}' parameter passed to the class method '${methodName}' is not a string.`
266
+ );
267
+ }
268
+ }
269
+ normalizeGroupName(value, descriptor, methodName) {
270
+ const normalized = value.trim().toLowerCase();
271
+ const match = MONTH_GROUP_NAMES.find((group) => group === normalized);
272
+ if (!match) {
273
+ throw new Error(
274
+ `ArabicDate class error: Unknown ${descriptor} group name '${value}' passed to the class method '${methodName}'.`
275
+ );
276
+ }
277
+ return match;
278
+ }
279
+ }
280
+ _date = new WeakMap();
281
+ _year = new WeakMap();
282
+ _monthIndex = new WeakMap();
283
+ _day = new WeakMap();
284
+ const VALID_FORMATS = /* @__PURE__ */ new Set(["H", "HM", "HMS", "HMSF"]);
285
+ const normalizeFormat = (format) => {
286
+ const value = format.toUpperCase();
287
+ if (!VALID_FORMATS.has(value)) {
288
+ throw new Error(
289
+ "ArabicTime class error: Invalid format string passed to the class method 'time'. Valid values are 'HMSF', 'HMS', 'HM' and 'H'."
290
+ );
291
+ }
292
+ return value;
293
+ };
294
+ class ArabicTime {
295
+ constructor(timeObject) {
296
+ __privateAdd(this, _time);
297
+ __privateAdd(this, _hour);
298
+ __privateAdd(this, _minute);
299
+ __privateAdd(this, _second);
300
+ __privateAdd(this, _milliseconds);
301
+ this.setTime(timeObject);
302
+ }
303
+ get timeObject() {
304
+ return new Date(__privateGet(this, _time));
305
+ }
306
+ set timeObject(value) {
307
+ this.setTime(value);
308
+ }
309
+ time(format = "HMS", separator = ":") {
310
+ this.assertString(format, "format", "time");
311
+ this.assertString(separator, "separator", "time");
312
+ const normalizedFormat = normalizeFormat(format);
313
+ const formattedParts = [];
314
+ if (normalizedFormat.includes("H")) {
315
+ formattedParts.push(toArabicDigits(__privateGet(this, _hour)));
316
+ }
317
+ if (normalizedFormat.includes("M")) {
318
+ formattedParts.push(toArabicDigits(__privateGet(this, _minute)));
319
+ }
320
+ if (normalizedFormat.includes("S")) {
321
+ formattedParts.push(toArabicDigits(__privateGet(this, _second)));
322
+ }
323
+ if (normalizedFormat.includes("F")) {
324
+ formattedParts.push(toArabicDigits(__privateGet(this, _milliseconds)));
325
+ }
326
+ return formattedParts.join(separator);
327
+ }
328
+ setTime(value) {
329
+ if (!isValidDate(value)) {
330
+ const message = value instanceof Date ? "ArabicTime class error: The parameter passed as timeObject is an invalid Date. Only valid Date objects are allowed." : "ArabicTime class error: The parameter passed as timeObject is not a Date. Only Date objects are allowed.";
331
+ throw new TypeError(message);
332
+ }
333
+ __privateSet(this, _time, new Date(value));
334
+ __privateSet(this, _hour, __privateGet(this, _time).getHours().toString());
335
+ __privateSet(this, _minute, __privateGet(this, _time).getMinutes().toString());
336
+ __privateSet(this, _second, __privateGet(this, _time).getSeconds().toString());
337
+ __privateSet(this, _milliseconds, __privateGet(this, _time).getMilliseconds().toString().padStart(3, "0"));
338
+ }
339
+ assertString(value, parameterName, methodName) {
340
+ if (typeof value !== "string") {
341
+ throw new TypeError(
342
+ `ArabicTime class error: The '${parameterName}' parameter passed to the class method '${methodName}' is not a string.`
343
+ );
344
+ }
345
+ }
346
+ }
347
+ _time = new WeakMap();
348
+ _hour = new WeakMap();
349
+ _minute = new WeakMap();
350
+ _second = new WeakMap();
351
+ _milliseconds = new WeakMap();
352
+ exports.ArabicDate = ArabicDate;
353
+ exports.ArabicTime = ArabicTime;
354
+ //# sourceMappingURL=arabic-datetime.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arabic-datetime.cjs","sources":["../src/constants.ts","../src/arabicNumerals.ts","../src/validators.ts","../src/arabicDate.ts","../src/arabicTime.ts"],"sourcesContent":["/** @internal */\nexport const AR_NUMS = {\n \"0\": \"٠\",\n \"1\": \"١\",\n \"2\": \"٢\",\n \"3\": \"٣\",\n \"4\": \"٤\",\n \"5\": \"٥\",\n \"6\": \"٦\",\n \"7\": \"٧\",\n \"8\": \"٨\",\n \"9\": \"٩\"\n} as const;\n\n/** @internal */\nexport type ArabicDigit = keyof typeof AR_NUMS;\n\n/** @internal */\nexport const MONTH_GROUP_NAMES = [\n \"syriac\",\n \"roman1\",\n \"roman2\",\n \"roman3\",\n \"french\"\n] as const;\n\n/** @internal */\nexport type MonthGroupName = (typeof MONTH_GROUP_NAMES)[number];\n\n/** @internal */\nexport const COUNTRY_CODES = [\n \"IQ\",\n \"JO\",\n \"LB\",\n \"PS\",\n \"SO\",\n \"SY\",\n \"BH\",\n \"KM\",\n \"DJ\",\n \"EG\",\n \"KW\",\n \"LY\",\n \"OM\",\n \"QA\",\n \"SA\",\n \"SD\",\n \"AE\",\n \"YE\",\n \"MA\",\n \"MR\",\n \"DZ\",\n \"TN\"\n] as const;\n\n/** @internal */\nexport type CountryCode = (typeof COUNTRY_CODES)[number];\n\n/** @internal */\nexport const isCountryCode = (value: string): value is CountryCode =>\n COUNTRY_CODES.includes(value as CountryCode);\n\n/** @internal */\nexport type MonthGroup = {\n readonly eastNums: boolean;\n readonly months: readonly [\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string\n ];\n readonly countries: readonly CountryCode[];\n};\n\n/** @internal */\nexport const MONTH_GROUPS: Record<MonthGroupName, MonthGroup> = {\n syriac: {\n eastNums: true,\n months: [\n \"كانون الثاني\",\n \"شباط\",\n \"آذار\",\n \"نيسان\",\n \"أيار\",\n \"حزيران\",\n \"تموز\",\n \"آب\",\n \"أيلول\",\n \"تشرين الأول\",\n \"تشرين الثاني\",\n \"كانون الأول\"\n ] as const,\n countries: [\"IQ\", \"JO\", \"LB\", \"PS\", \"SY\"] as const\n },\n roman1: {\n eastNums: true,\n months: [\n \"يناير\",\n \"فبراير\",\n \"مارس\",\n \"أبريل\",\n \"مايو\",\n \"يونيو\",\n \"يوليو\",\n \"أغسطس\",\n \"سبتمبر\",\n \"أكتوبر\",\n \"نوفمبر\",\n \"ديسمبر\"\n ] as const,\n countries: [\"BH\", \"KM\", \"DJ\", \"EG\", \"KW\", \"LY\", \"OM\", \"QA\", \"SA\", \"SO\", \"SD\", \"AE\", \"YE\"] as const\n },\n roman2: {\n eastNums: false,\n months: [\n \"يناير\",\n \"فبراير\",\n \"مارس\",\n \"أبريل\",\n \"ماي\",\n \"يونيو\",\n \"يوليوز\",\n \"غشت\",\n \"شتنبر\",\n \"أكتوبر\",\n \"نونبر\",\n \"دجنبر\"\n ] as const,\n countries: [\"MA\"] as const\n },\n roman3: {\n eastNums: false,\n months: [\n \"يناير\",\n \"فبراير\",\n \"مارس\",\n \"إبريل\",\n \"مايو\",\n \"يونيو\",\n \"يوليو\",\n \"أغشت\",\n \"شتمبر\",\n \"أكتوبر\",\n \"نوفمبر\",\n \"ديسمبر\"\n ] as const,\n countries: [\"MR\"] as const\n },\n french: {\n eastNums: false,\n months: [\n \"جانفي\",\n \"فيفري\",\n \"مارس\",\n \"أفريل\",\n \"ماي\",\n \"جوان\",\n \"جويلية\",\n \"أوت\",\n \"سبتمبر\",\n \"أكتوبر\",\n \"نوفمبر\",\n \"ديسمبر\"\n ] as const,\n countries: [\"DZ\", \"TN\"] as const\n }\n};\n","import { AR_NUMS, type ArabicDigit } from './constants';\n\n\nconst WESTERN_DIGIT_PATTERN = /[0-9]/g;\n\n/** @internal */\nexport const toArabicDigits = (value: string): string =>\n value.replace(WESTERN_DIGIT_PATTERN, (digit) => AR_NUMS[digit as ArabicDigit]);\n","/** @internal */\nexport const isValidDate = (value: unknown): value is Date =>\n value instanceof Date && !Number.isNaN(value.valueOf());\n","import { MONTH_GROUPS, MONTH_GROUP_NAMES, isCountryCode, type MonthGroupName } from './constants';\nimport { toArabicDigits } from './arabicNumerals';\nimport { isValidDate } from './validators';\n\nexport class ArabicDate {\n #date!: Date;\n #year!: string;\n #monthIndex!: number;\n #day!: string;\n\n constructor(dateObject: Date) {\n this.setDate(dateObject);\n }\n\n get dateObject(): Date {\n return new Date(this.#date);\n }\n\n set dateObject(value: Date) {\n this.setDate(value);\n }\n\n syriacNames(eastNums: boolean = false): string {\n this.assertBoolean(eastNums, 'syriacNames');\n return this.composeGroupFormat('syriac', eastNums);\n }\n\n roman1Names(eastNums: boolean = false): string {\n this.assertBoolean(eastNums, 'roman1Names');\n return this.composeGroupFormat('roman1', eastNums);\n }\n\n roman2Names(eastNums: boolean = false): string {\n this.assertBoolean(eastNums, 'roman2Names');\n return this.composeGroupFormat('roman2', eastNums);\n }\n\n roman3Names(eastNums: boolean = false): string {\n this.assertBoolean(eastNums, 'roman3Names');\n return this.composeGroupFormat('roman3', eastNums);\n }\n\n frenchNames(eastNums: boolean = false): string {\n this.assertBoolean(eastNums, 'frenchNames');\n return this.composeGroupFormat('french', eastNums);\n }\n\n dualNames(first: string, second: string, eastNums: boolean = false): string {\n this.assertString(first, 'first', 'dualNames');\n this.assertString(second, 'second', 'dualNames');\n this.assertBoolean(eastNums, 'dualNames');\n\n const normalizedFirst = this.normalizeGroupName(first, 'first', 'dualNames');\n const normalizedSecond = this.normalizeGroupName(second, 'second', 'dualNames');\n\n if (normalizedFirst === normalizedSecond) {\n throw new Error(\n \"ArabicDate class error: The first group name and the second group name should not be identical in the parameters passed to the method 'dualNames'.\"\n );\n }\n\n const day = this.formatDay(eastNums);\n const year = this.formatYear(eastNums);\n const firstMonth = MONTH_GROUPS[normalizedFirst].months[this.#monthIndex];\n const secondMonth = MONTH_GROUPS[normalizedSecond].months[this.#monthIndex];\n\n return `${day} ${firstMonth} (${secondMonth}) ${year}`;\n }\n\n byCountryCode(countryCode: string, eastNums?: boolean): string {\n this.assertString(countryCode, 'country_code', 'byCountryCode');\n\n if (eastNums !== undefined) {\n this.assertBoolean(eastNums, 'byCountryCode');\n }\n\n const normalizedCode = countryCode.trim().toUpperCase();\n if (!normalizedCode) {\n throw new Error(\n \"ArabicDate class error: Unknown country code '' passed to the class method 'byCountryCode'.\"\n );\n }\n\n if (!isCountryCode(normalizedCode)) {\n throw new Error(\n `ArabicDate class error: Unknown country code '${countryCode}' passed to the class method 'byCountryCode'.`\n );\n }\n\n for (const groupName of MONTH_GROUP_NAMES) {\n const group = MONTH_GROUPS[groupName];\n if (group.countries.includes(normalizedCode)) {\n const east = eastNums ?? group.eastNums;\n return this.composeGroupFormat(groupName, east);\n }\n }\n\n throw new Error(\n `ArabicDate class error: Unknown country code '${countryCode}' passed to the class method 'byCountryCode'.`\n );\n }\n\n easternNumericDate(separator: string = '/'): string {\n this.assertString(separator, 'separator', 'easternNumericDate');\n const month = (this.#monthIndex + 1).toString();\n return [this.#day, month, this.#year].map(toArabicDigits).join(separator);\n }\n\n private setDate(value: unknown): void {\n if (!isValidDate(value)) {\n const message = value instanceof Date\n ? \"ArabicDate class error: The parameter passed as dateObject is an invalid Date. Only valid Date objects are allowed.\"\n : \"ArabicDate class error: The parameter passed as dateObject is not a Date. Only Date objects are allowed.\";\n throw new TypeError(message);\n }\n\n this.#date = new Date(value);\n this.#year = this.#date.getFullYear().toString();\n this.#monthIndex = this.#date.getMonth();\n this.#day = this.#date.getDate().toString();\n }\n\n private composeGroupFormat(groupName: MonthGroupName, eastNums: boolean): string {\n const day = this.formatDay(eastNums);\n const month = MONTH_GROUPS[groupName].months[this.#monthIndex];\n const year = this.formatYear(eastNums);\n return `${day} ${month} ${year}`;\n }\n\n private formatDay(eastNums: boolean): string {\n return eastNums ? toArabicDigits(this.#day) : this.#day;\n }\n\n private formatYear(eastNums: boolean): string {\n return eastNums ? toArabicDigits(this.#year) : this.#year;\n }\n\n private assertBoolean(value: unknown, methodName: string): asserts value is boolean {\n if (typeof value !== 'boolean') {\n throw new TypeError(\n `ArabicDate class error: east_nums must be a boolean. '${String(value)}' is not a boolean and was passed to the class method '${methodName}'.`\n );\n }\n }\n\n private assertString(value: unknown, parameterName: string, methodName: string): asserts value is string {\n if (typeof value !== 'string') {\n throw new TypeError(\n `ArabicDate class error: The '${parameterName}' parameter passed to the class method '${methodName}' is not a string.`\n );\n }\n }\n\n private normalizeGroupName(value: string, descriptor: string, methodName: string): MonthGroupName {\n const normalized = value.trim().toLowerCase();\n const match = MONTH_GROUP_NAMES.find((group) => group === normalized);\n\n if (!match) {\n throw new Error(\n `ArabicDate class error: Unknown ${descriptor} group name '${value}' passed to the class method '${methodName}'.`\n );\n }\n\n return match;\n }\n}\n","import { toArabicDigits } from './arabicNumerals';\nimport { isValidDate } from './validators';\n\nconst VALID_FORMATS = new Set(['H', 'HM', 'HMS', 'HMSF']);\n\ntype AcceptedFormat = 'H' | 'HM' | 'HMS' | 'HMSF';\n\nconst normalizeFormat = (format: string): AcceptedFormat => {\n const value = format.toUpperCase();\n if (!VALID_FORMATS.has(value)) {\n throw new Error(\n \"ArabicTime class error: Invalid format string passed to the class method 'time'. Valid values are 'HMSF', 'HMS', 'HM' and 'H'.\"\n );\n }\n return value as AcceptedFormat;\n};\n\nexport class ArabicTime {\n #time!: Date;\n #hour!: string;\n #minute!: string;\n #second!: string;\n #milliseconds!: string;\n\n constructor(timeObject: Date) {\n this.setTime(timeObject);\n }\n\n get timeObject(): Date {\n return new Date(this.#time);\n }\n\n set timeObject(value: Date) {\n this.setTime(value);\n }\n\n time(format: string = 'HMS', separator: string = ':'): string {\n this.assertString(format, 'format', 'time');\n this.assertString(separator, 'separator', 'time');\n\n const normalizedFormat = normalizeFormat(format);\n const formattedParts: string[] = [];\n\n if (normalizedFormat.includes('H')) {\n formattedParts.push(toArabicDigits(this.#hour));\n }\n if (normalizedFormat.includes('M')) {\n formattedParts.push(toArabicDigits(this.#minute));\n }\n if (normalizedFormat.includes('S')) {\n formattedParts.push(toArabicDigits(this.#second));\n }\n if (normalizedFormat.includes('F')) {\n formattedParts.push(toArabicDigits(this.#milliseconds));\n }\n\n return formattedParts.join(separator);\n }\n\n private setTime(value: unknown): void {\n if (!isValidDate(value)) {\n const message = value instanceof Date\n ? \"ArabicTime class error: The parameter passed as timeObject is an invalid Date. Only valid Date objects are allowed.\"\n : \"ArabicTime class error: The parameter passed as timeObject is not a Date. Only Date objects are allowed.\";\n throw new TypeError(message);\n }\n\n this.#time = new Date(value);\n this.#hour = this.#time.getHours().toString();\n this.#minute = this.#time.getMinutes().toString();\n this.#second = this.#time.getSeconds().toString();\n this.#milliseconds = this.#time.getMilliseconds().toString().padStart(3, '0');\n }\n\n private assertString(value: unknown, parameterName: string, methodName: string): asserts value is string {\n if (typeof value !== 'string') {\n throw new TypeError(\n `ArabicTime class error: The '${parameterName}' parameter passed to the class method '${methodName}' is not a string.`\n );\n }\n }\n}\n"],"names":[],"mappings":"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"}