bn-calendar 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1,1118 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./convert-3jw8Rx7e.cjs`);function t(t){let n=e.r(t);return n?n%4==0&&n%100!=0||n%400==0:!1}const n=864e5,r=Object.freeze({"revised-2019":{normal:[31,31,31,31,31,31,30,30,30,30,29,30],leap:[31,31,31,31,31,31,30,30,30,30,30,30]},"revised-1966":{normal:[31,31,31,31,31,30,30,30,30,30,30,30],leap:[31,31,31,31,31,30,30,30,30,30,31,30]}}),i=Object.freeze([{bn:`গ্রীষ্ম`,en:`Grisma (Summer)`},{bn:`বর্ষা`,en:`Barsa (Monsoon)`},{bn:`শরৎ`,en:`Sarat (Autumn)`},{bn:`হেমন্ত`,en:`Hemanta (Late-Autumn)`},{bn:`শীত`,en:`Shhit (Winter)`},{bn:`বসন্ত`,en:`Basanta (Spring)`}]),a=Object.freeze([{bn:`রবিবার`,en:`Robibar (Sunday)`,short:`র`},{bn:`সোমবার`,en:`Shombar (Monday)`,short:`সো`},{bn:`মঙ্গলবার`,en:`Mongolbar (Tuesday)`,short:`ম`},{bn:`বুধবার`,en:`Budhbar (Wednesday)`,short:`বু`},{bn:`বৃহস্পতিবার`,en:`Brihoshpotibar (Thursday)`,short:`বৃ`},{bn:`শুক্রবার`,en:`Shukrobar (Friday)`,short:`শু`},{bn:`শনিবার`,en:`Shonibar (Saturday)`,short:`শ`}]),o=Object.freeze([{bn:`বৈশাখ`,en:`Boishakh`,short:`বৈ`},{bn:`জ্যৈষ্ঠ`,en:`Joishtho`,short:`জ্য`},{bn:`আষাঢ়`,en:`Asharh`,short:`আ`},{bn:`শ্রাবণ`,en:`Srabon`,short:`শ্রা`},{bn:`ভাদ্র`,en:`Bhadro`,short:`ভা`},{bn:`আশ্বিন`,en:`Ashwin`,short:`আ`},{bn:`কার্তিক`,en:`Kartik`,short:`কা`},{bn:`অগ্রহায়ণ`,en:`Ogrohayon`,short:`অ`},{bn:`পৌষ`,en:`Poush`,short:`পৌ`},{bn:`মাঘ`,en:`Magh`,short:`মা`},{bn:`ফাল্গুন`,en:`Falgun`,short:`ফা`},{bn:`চৈত্র`,en:`Choitro`,short:`চৈ`}]),s=Object.freeze([`YYYY`,`YY`,`yyyy`,`yy`]),c=Object.freeze([`M`,`MM`,`mmm`,`mmmm`]),l=Object.freeze([`DD`,`D`,`Do`]),u=Object.freeze([`d`,`dd`,`ddd`]),d=Object.freeze([`H`,`HH`,`hh`,`h`]),f=Object.freeze([`mm`,`m`]),p=Object.freeze([`ss`,`s`]),m=Object.freeze([`ms`,`mss`]),h=Object.freeze([`a`,`A`]),g=Object.freeze([`Z`,`ZZ`,`S`,`SS`]),_=Object.freeze([...s,...c,...u,...l,...d,...f,...p,...m,...h,...g].sort((e,t)=>t.length-e.length));function v(e,t){let n=RegExp(`^(${_.join(`|`)})`),r=``,i=0;for(;i<e.length;){if(e[i]===`[`){let t=e.indexOf(`]`,i);if(t!==-1){r+=e.slice(i+1,t),i=t+1;continue}}let a=n.exec(e.slice(i));a?(r+=t[a[0]]??a[0],i+=a[0].length):(r+=e[i],i++)}return r}function y(e,n,r){return r===`revised-1966`?e%4==2:t(n)}function b(e,t){let n=i[Math.floor(e/2)];return t===`en`?n.en:n.bn}function x(e){let t=e.getMonth();return{gy:e.getFullYear(),$gm:t,gm:t+1,gd:e.getDate(),wd:e.getDay()}}function S(e){let{gy:t,gm:n,gd:r}=x(e);return n<4||n===4&&r<14?t-1:t}function C(e){return S(e)-593}function w(e){let{gy:t,$gm:n,gd:r}=x(e);return Date.UTC(t,n,r)}function T(e){return Math.floor((w(e)-Date.UTC(S(e),3,14))/n)}function E(e,t){let n=t??`revised-2019`,i=y(C(e),e.getFullYear(),n)?r?.[n].leap:r?.[n].normal,a=T(e),o=0;for(;a>=i[o];)a-=i[o],o++;return{days:a,monthIdx:o}}function D(e,t=2){return e.padStart(t,`০`)}var O=class t{variant;year;month;date;gregorian;weekDay;isoWeekDay;constructor(n,r,i,a){this.variant=this.#r(n,r,i,a);let o=n instanceof Date?n:new Date(e.i(n)&&!t.isBanglaDateString(n)||e.c(n)&&!t.isBanglaYearEn(n)?n:Date.now());isNaN(o.getTime())&&(o=new Date);let{year:s,month:c,monthDate:l}=this.#i(o),u=t.isBanglaYear(n)?e.t(n):e.c(n)&&t.isBanglaYearEn(n)?n:s,d=t.isBanglaMonth(r)?e.t(r):t.isBanglaMonthEn(r)?r:c,f=t.isBanglaDate(i)?e.t(i):t.isBanglaDateEn(i)?i:l;if(t.isBanglaDateString(n)){let t=n.replace(/['"]/g,``).split(`-`);u=e.t(t[0]),d=e.t(t[1]),f=e.t(t[2])}let{gregYear:p}=this.#e(u,d),{bnMonthTable:m}=this.#t(p,u),h=m[d-1];f>h&&(f-=h,d===12?(d=1,u+=1):d+=1),this.year={bn:e.n(u),en:u},this.month={bn:e.n(d),en:d},this.date={bn:e.n(f),en:f};let{gy:g,gm:_,gd:v,wd:y}=x(this.toDate());this.gregorian={year:g,month:_,date:v},this.weekDay=y,this.isoWeekDay=y===0?7:y}[Symbol.toPrimitive](e){return e===`number`?this.valueOf():this.toJSON()}get[Symbol.toStringTag](){return this.toJSON()}valueOf(){return this.toDate().getTime()}toJSON(){let{year:e,month:t,date:n}=this;return`${D(e.bn,4)}-${D(t.bn)}-${D(n.bn)}`}isLeapYear(){let{gregYear:e}=this.#e();return this.#t(e).isBnLeapYear}toDate(){let{baseGregYear:e,gregYear:t}=this.#e(),{bnMonthTable:r}=this.#t(t),i=Date.UTC(e,3,13),a=this.date.en;for(let e=0;e<this.month.en-1;e++)a+=r[e];return new Date(a*n+i)}getSeasonName(e){return b(this.month.en-1,e)}getMonthName(e){let t=o[this.month.en-1];return e===`en`?t.en:t.bn}getDayName(e){let t=a[this.weekDay];return e===`en`?t.en:t.bn}addDays(e){let n=this.toDate();return new t(n.setDate(n.getDate()+e),{variant:this.variant})}addWeeks(e){let n=this.toDate();return new t(n.setDate(n.getDate()+e*7),{variant:this.variant})}addMonths(e,n=!0){if(n){let n=this.toDate();return new t(n.setMonth(n.getMonth()+e),{variant:this.variant})}else{let{variant:t,year:n,month:r,date:i}=this,a=r.en+e,o=n.en;for(;a>12;)a-=12,o+=1;for(;a<1;)a+=12,--o;return this.#n(o,a,i.en,t)}}addYears(e,n=!0){let{variant:r,year:i,month:a,date:o}=this,s=i.en+e;return n?new t(s,a.en,o.en,{variant:r}):this.#n(s,a.en,o.en,r)}startOfMonth(){let{year:e,month:n,variant:r}=this;return new t(e.en,n.en,1,{variant:r})}endOfMonth(){let{year:e,month:n,variant:r}=this;return new t(e.en,n.en,this.daysInMonth(),{variant:r})}startOfYear(){let{year:e,variant:n}=this;return new t(e.en,1,1,{variant:n})}endOfYear(){let{year:e,variant:n}=this;return new t(e.en,12,30,{variant:n})}daysInMonth(e){let{gregYear:t}=this.#e(),{bnMonthTable:n}=this.#t(t);return n[(e??this.month.en)-1]}toString(){return this.#a(`bn`)}toStringEn(){return this.#a(`en`)}format(e){let{year:t,month:n,date:r,weekDay:i}=this,s=this.getSeasonName(),c=o[n.en-1],l=a[i],u=D(t.bn,4),d={YYYY:u,YY:u.slice(-2),yyyy:u,yy:u.slice(-2),M:n.bn,MM:D(n.bn),mmm:c.short,mmmm:c.bn,d:l.short,dd:l.bn.replace(`বার`,``),ddd:l.bn,D:r.bn,DD:D(r.bn),Do:r.bn,S:s,SS:s+`কাল`};return v(e||`ddd, DD mmmm (SS), YYYY বঙ্গাব্দ`,d)}#e(e,t){let n=(e??this.year.en)+593;return{baseGregYear:n,gregYear:(t??this.month.en)>10?n+1:n}}#t(e,t){let n=y(t??this.year.en,e,this.variant);return{bnMonthTable:n?r?.[this.variant].leap:r?.[this.variant].normal,isBnLeapYear:n}}#n(e,n,r,i){let{gregYear:a}=this.#e(e,n),{bnMonthTable:o}=this.#t(a,e);return new t(e,n,Math.min(r,o[n-1]),{variant:i})}#r(e,t,n,r){return this.$hasVariantConfig(e)?e.variant:this.$hasVariantConfig(t)?t.variant:this.$hasVariantConfig(n)?n.variant:this.$hasVariantConfig(r)?r.variant:`revised-2019`}#i(e){let t=C(e),{days:n,monthIdx:r}=E(e,this.variant);return{year:t,month:r+1,monthDate:n+1}}#a(e=`bn`){let{year:t,date:n}=this;return`${this.getDayName(e)}, ${n[e]} ${this.getMonthName(e)}, ${t[e]} [${this.getSeasonName(e)}]`}$hasVariantConfig(t){return e.a(t,[`variant`])&&e.s(t.variant)&&(t.variant===`revised-1966`||t.variant===`revised-2019`)}static isBanglaYear(t){return e.s(t)&&/^(?:০{0,3}[১-৯][০-৯]{0,3}|০)$/.test(t.trim())}static isBanglaYearEn(t){return e.o(t)&&t>=0&&t<=9999}static isBanglaMonth(t){return e.s(t)&&/^(?:০?[১-৯]|১০|১১|১২)$/.test(t.trim())}static isBanglaMonthEn(t){return e.o(t)&&t>=1&&t<=12}static isBanglaDate(t){return e.s(t)&&/^(?:০?[১-৯]|[১২][০-৯]|৩০|৩১)$/.test(t.trim())}static isBanglaDateEn(t){return e.o(t)&&t>=1&&t<=31}static isBanglaDateString(n){if(e.s(n)&&n.includes(`-`)){let[e,r,i]=n.replace(/['"]/g,``).split(`-`);return t.isBanglaYear(e)&&t.isBanglaMonth(r)&&t.isBanglaDate(i)}return!1}};exports.BanglaCalendar=O,exports.BnCalendar=O,exports.Bongabdo=O;
1
+ /**
2
+ * Copyright 2026 - present Nazmul Hassan
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
18
+ const require_convert = require('./convert-CuE2E2-u.cjs');
19
+
20
+ //#region node_modules/.pnpm/nhb-toolbox@4.30.1/node_modules/nhb-toolbox/dist/esm/date/guards.js
21
+ function isLeapYear(year) {
22
+ const $year = require_convert.normalizeNumber(year);
23
+ return $year ? $year % 4 === 0 && $year % 100 !== 0 || $year % 400 === 0 : false;
24
+ }
25
+
26
+ //#endregion
27
+ //#region src/constants.ts
28
+ /** Milliseconds per day */
29
+ const MS_PER_DAY = 864e5;
30
+ /** Bangla month days table for different variants */
31
+ const BN_MONTH_TABLES = /* @__PURE__ */ Object.freeze({
32
+ "revised-2019": {
33
+ normal: [
34
+ 31,
35
+ 31,
36
+ 31,
37
+ 31,
38
+ 31,
39
+ 31,
40
+ 30,
41
+ 30,
42
+ 30,
43
+ 30,
44
+ 29,
45
+ 30
46
+ ],
47
+ leap: [
48
+ 31,
49
+ 31,
50
+ 31,
51
+ 31,
52
+ 31,
53
+ 31,
54
+ 30,
55
+ 30,
56
+ 30,
57
+ 30,
58
+ 30,
59
+ 30
60
+ ]
61
+ },
62
+ "revised-1966": {
63
+ normal: [
64
+ 31,
65
+ 31,
66
+ 31,
67
+ 31,
68
+ 31,
69
+ 30,
70
+ 30,
71
+ 30,
72
+ 30,
73
+ 30,
74
+ 30,
75
+ 30
76
+ ],
77
+ leap: [
78
+ 31,
79
+ 31,
80
+ 31,
81
+ 31,
82
+ 31,
83
+ 30,
84
+ 30,
85
+ 30,
86
+ 30,
87
+ 30,
88
+ 31,
89
+ 30
90
+ ]
91
+ }
92
+ });
93
+ /** List of Bangla season names in Bangla and English */
94
+ const BN_SEASONS = /* @__PURE__ */ Object.freeze([
95
+ {
96
+ bn: "গ্রীষ্ম",
97
+ en: "Grisma (Summer)"
98
+ },
99
+ {
100
+ bn: "বর্ষা",
101
+ en: "Barsa (Monsoon)"
102
+ },
103
+ {
104
+ bn: "শরৎ",
105
+ en: "Sarat (Autumn)"
106
+ },
107
+ {
108
+ bn: "হেমন্ত",
109
+ en: "Hemanta (Late-Autumn)"
110
+ },
111
+ {
112
+ bn: "শীত",
113
+ en: "Shhit (Winter)"
114
+ },
115
+ {
116
+ bn: "বসন্ত",
117
+ en: "Basanta (Spring)"
118
+ }
119
+ ]);
120
+ /** List of Bangla day names in Bangla and English */
121
+ const BN_DAYS = /* @__PURE__ */ Object.freeze([
122
+ {
123
+ bn: "রবিবার",
124
+ en: "Robibar (Sunday)",
125
+ short: "র"
126
+ },
127
+ {
128
+ bn: "সোমবার",
129
+ en: "Shombar (Monday)",
130
+ short: "সো"
131
+ },
132
+ {
133
+ bn: "মঙ্গলবার",
134
+ en: "Mongolbar (Tuesday)",
135
+ short: "ম"
136
+ },
137
+ {
138
+ bn: "বুধবার",
139
+ en: "Budhbar (Wednesday)",
140
+ short: "বু"
141
+ },
142
+ {
143
+ bn: "বৃহস্পতিবার",
144
+ en: "Brihoshpotibar (Thursday)",
145
+ short: "বৃ"
146
+ },
147
+ {
148
+ bn: "শুক্রবার",
149
+ en: "Shukrobar (Friday)",
150
+ short: "শু"
151
+ },
152
+ {
153
+ bn: "শনিবার",
154
+ en: "Shonibar (Saturday)",
155
+ short: "শ"
156
+ }
157
+ ]);
158
+ /** List of Bangla month names in Bangla and English */
159
+ const BN_MONTHS = /* @__PURE__ */ Object.freeze([
160
+ {
161
+ bn: "বৈশাখ",
162
+ en: "Boishakh",
163
+ short: "বৈ"
164
+ },
165
+ {
166
+ bn: "জ্যৈষ্ঠ",
167
+ en: "Joishtho",
168
+ short: "জ্য"
169
+ },
170
+ {
171
+ bn: "আষাঢ়",
172
+ en: "Asharh",
173
+ short: "আ"
174
+ },
175
+ {
176
+ bn: "শ্রাবণ",
177
+ en: "Srabon",
178
+ short: "শ্রা"
179
+ },
180
+ {
181
+ bn: "ভাদ্র",
182
+ en: "Bhadro",
183
+ short: "ভা"
184
+ },
185
+ {
186
+ bn: "আশ্বিন",
187
+ en: "Ashwin",
188
+ short: "আ"
189
+ },
190
+ {
191
+ bn: "কার্তিক",
192
+ en: "Kartik",
193
+ short: "কা"
194
+ },
195
+ {
196
+ bn: "অগ্রহায়ণ",
197
+ en: "Ogrohayon",
198
+ short: "অ"
199
+ },
200
+ {
201
+ bn: "পৌষ",
202
+ en: "Poush",
203
+ short: "পৌ"
204
+ },
205
+ {
206
+ bn: "মাঘ",
207
+ en: "Magh",
208
+ short: "মা"
209
+ },
210
+ {
211
+ bn: "ফাল্গুন",
212
+ en: "Falgun",
213
+ short: "ফা"
214
+ },
215
+ {
216
+ bn: "চৈত্র",
217
+ en: "Choitro",
218
+ short: "চৈ"
219
+ }
220
+ ]);
221
+ const YEAR_FORMATS = /* @__PURE__ */ Object.freeze([
222
+ "YYYY",
223
+ "YY",
224
+ "yyyy",
225
+ "yy"
226
+ ]);
227
+ const MONTH_FORMATS = /* @__PURE__ */ Object.freeze([
228
+ "M",
229
+ "MM",
230
+ "mmm",
231
+ "mmmm"
232
+ ]);
233
+ const DATE_FORMATS = /* @__PURE__ */ Object.freeze([
234
+ "DD",
235
+ "D",
236
+ "Do"
237
+ ]);
238
+ const DAY_FORMATS = /* @__PURE__ */ Object.freeze([
239
+ "d",
240
+ "dd",
241
+ "ddd"
242
+ ]);
243
+ const HOUR_FORMATS = /* @__PURE__ */ Object.freeze([
244
+ "H",
245
+ "HH",
246
+ "hh",
247
+ "h"
248
+ ]);
249
+ const MINUTE_FORMATS = /* @__PURE__ */ Object.freeze(["mm", "m"]);
250
+ const SECOND_FORMATS = /* @__PURE__ */ Object.freeze(["ss", "s"]);
251
+ const MILLISECOND_FORMATS = /* @__PURE__ */ Object.freeze(["ms", "mss"]);
252
+ const TIME_FORMATS = /* @__PURE__ */ Object.freeze(["a", "A"]);
253
+ const EXTRA_FORMATS = /* @__PURE__ */ Object.freeze([
254
+ "Z",
255
+ "ZZ",
256
+ "S",
257
+ "SS"
258
+ ]);
259
+ const SORTED_TIME_FORMATS = /* @__PURE__ */ Object.freeze([
260
+ ...YEAR_FORMATS,
261
+ ...MONTH_FORMATS,
262
+ ...DAY_FORMATS,
263
+ ...DATE_FORMATS,
264
+ ...HOUR_FORMATS,
265
+ ...MINUTE_FORMATS,
266
+ ...SECOND_FORMATS,
267
+ ...MILLISECOND_FORMATS,
268
+ ...TIME_FORMATS,
269
+ ...EXTRA_FORMATS
270
+ ].sort((a, b) => b.length - a.length));
271
+
272
+ //#endregion
273
+ //#region src/helpers.ts
274
+ /** Core formatting logic shared by `formatDate` and `Chronos`, `BanglaCalendar` classes */
275
+ function _formatDateCore(format, dateComponents) {
276
+ const tokenRegex = new RegExp(`^(${SORTED_TIME_FORMATS.join("|")})`);
277
+ let result = "";
278
+ let i = 0;
279
+ while (i < format.length) {
280
+ if (format[i] === "[") {
281
+ const end = format.indexOf("]", i);
282
+ if (end !== -1) {
283
+ result += format.slice(i + 1, end);
284
+ i = end + 1;
285
+ continue;
286
+ }
287
+ }
288
+ const match = tokenRegex.exec(format.slice(i));
289
+ if (match) {
290
+ result += dateComponents[match[0]] ?? match[0];
291
+ i += match[0].length;
292
+ } else {
293
+ result += format[i];
294
+ i++;
295
+ }
296
+ }
297
+ return result;
298
+ }
299
+ /** Check whether a Bangla year is leap by Gregorian and Bangla years and calendar variant */
300
+ function _isBnLeapYear(by, gy, v) {
301
+ return v === "revised-1966" ? by % 4 === 2 : isLeapYear(gy);
302
+ }
303
+ /** Get Bangla season name by month index (`0-11`) */
304
+ function _getBnSeason(month, locale) {
305
+ const season = BN_SEASONS[Math.floor(month / 2)];
306
+ return locale === "en" ? season.en : season.bn;
307
+ }
308
+ /** Extract selective unit values from {@link Date} object */
309
+ function _extractDateUnits(date) {
310
+ const month = date.getMonth();
311
+ return {
312
+ gy: date.getFullYear(),
313
+ $gm: month,
314
+ gm: month + 1,
315
+ gd: date.getDate(),
316
+ wd: date.getDay()
317
+ };
318
+ }
319
+ /** Get Gregorian base year from {@link Date} object for Bangla year */
320
+ function _getGregBaseYear(date) {
321
+ const { gy, gm, gd } = _extractDateUnits(date);
322
+ return gm < 4 || gm === 4 && gd < 14 ? gy - 1 : gy;
323
+ }
324
+ /** Get Bangla year from {@link Date} object */
325
+ function _getBnYear(date) {
326
+ return _getGregBaseYear(date) - 593;
327
+ }
328
+ /** Get timestamp in milliseconds between midnight, January 1, 1970 (UTC) and the specified {@link Date} object */
329
+ function _getUtcTs(date) {
330
+ const { gy, $gm, gd } = _extractDateUnits(date);
331
+ return Date.UTC(gy, $gm, gd);
332
+ }
333
+ /** Get number of days elapsed since midnight April 14, 1970 (UTC) for specific {@link Date} */
334
+ function _getElapsedDays(date) {
335
+ return Math.floor((_getUtcTs(date) - Date.UTC(_getGregBaseYear(date), 3, 14)) / MS_PER_DAY);
336
+ }
337
+ /** Get number of days elapsed since midnight April 14, 1970 (UTC) and month index for specific `Date` and Bangla calendar variant */
338
+ function _bnDaysMonthIdx(date, variant) {
339
+ const v = variant ?? "revised-2019";
340
+ const table = _isBnLeapYear(_getBnYear(date), date.getFullYear(), v) ? BN_MONTH_TABLES?.[v].leap : BN_MONTH_TABLES?.[v].normal;
341
+ let days = _getElapsedDays(date);
342
+ let monthIdx = 0;
343
+ while (days >= table[monthIdx]) {
344
+ days -= table[monthIdx];
345
+ monthIdx++;
346
+ }
347
+ return {
348
+ days,
349
+ monthIdx
350
+ };
351
+ }
352
+ /**
353
+ * Pad at the start of a string with Bangla zero (`'০'`)
354
+ * @param str String to pad with
355
+ * @param length Maximum length to pad, default is `2`
356
+ * @returns The padded string
357
+ */
358
+ function _padShunno(str, length = 2) {
359
+ return str.padStart(length, "০");
360
+ }
361
+
362
+ //#endregion
363
+ //#region src/BanglaCalendar.ts
364
+ /**
365
+ * @class Represents a date in the Bangla calendar system with support for different variants.
366
+ * - This class provides functionality to create, manipulate, convert dates between the Bangla and Gregorian calendar systems.
367
+ * - It supports two Bangla calendar variants: `'revised-2019'` (default) and `'revised-1966'`.
368
+ *
369
+ * @example
370
+ * // Create from current date
371
+ * const today = new BanglaCalendar();
372
+ *
373
+ * // Create from Bangla date string (Bangla digit)
374
+ * const date0 = new BanglaCalendar('১৪৩২-১১-০৮');
375
+ *
376
+ * // Create from Gregorian date
377
+ * const date1 = new BanglaCalendar('2023-04-14'); // Latin digit
378
+ * const date2 = new BanglaCalendar(new Date('2023-04-14')); // Date object
379
+ *
380
+ * // Create with specific Bangla date using Latin digits
381
+ * const date3 = new BanglaCalendar(1430, 1, 1);
382
+ *
383
+ * // Create with specific Bangla date using Bangla digits
384
+ * const date4 = new BanglaCalendar('১৪৩০', '১', '১');
385
+ *
386
+ * // Create with specific variant
387
+ * const date5 = new BanglaCalendar('১৪৩০', '১', '১', { variant: 'revised-1966' });
388
+ *
389
+ * @remarks
390
+ * - The Bangla calendar year starts on `April 14th (১ বৈশাখ)` in the Gregorian calendar.
391
+ * - The class automatically handles leap years according to the selected variant.
392
+ */
393
+ var BanglaCalendar = class BanglaCalendar {
394
+ /** Bangla calendar variant */
395
+ variant;
396
+ /** Bangla year */
397
+ year;
398
+ /** Bangla month */
399
+ month;
400
+ /** Bangla day of the month */
401
+ date;
402
+ /** Gregorian equivalent of the current bangla date */
403
+ gregorian;
404
+ /** Gets the day of the week (0-6, where 0 is Sunday (রবিবার)). */
405
+ weekDay;
406
+ /** Gets ISO weekday: 1 = Monday, 7 = Sunday */
407
+ isoWeekDay;
408
+ /** * Creates a `BanglaCalendar` instance based on given parameter(s) */
409
+ constructor(dateBnYrOrCfg, bnMonthOrCfg, bnDateOrCfg, config) {
410
+ this.variant = this.#processVariants(dateBnYrOrCfg, bnMonthOrCfg, bnDateOrCfg, config);
411
+ let date = dateBnYrOrCfg instanceof Date ? dateBnYrOrCfg : new Date(require_convert.isDateString(dateBnYrOrCfg) && !BanglaCalendar.isBanglaDateString(dateBnYrOrCfg) ? dateBnYrOrCfg : require_convert.isNumber(dateBnYrOrCfg) && !BanglaCalendar.isBanglaYearEn(dateBnYrOrCfg) ? dateBnYrOrCfg : Date.now());
412
+ if (isNaN(date.getTime())) date = /* @__PURE__ */ new Date();
413
+ const { year, month, monthDate } = this.#processDate(date);
414
+ let bnYear = BanglaCalendar.isBanglaYear(dateBnYrOrCfg) ? require_convert.banglaToDigit(dateBnYrOrCfg) : require_convert.isNumber(dateBnYrOrCfg) && BanglaCalendar.isBanglaYearEn(dateBnYrOrCfg) ? dateBnYrOrCfg : year;
415
+ let bnMonth = BanglaCalendar.isBanglaMonth(bnMonthOrCfg) ? require_convert.banglaToDigit(bnMonthOrCfg) : BanglaCalendar.isBanglaMonthEn(bnMonthOrCfg) ? bnMonthOrCfg : month;
416
+ let bnDate = BanglaCalendar.isBanglaDate(bnDateOrCfg) ? require_convert.banglaToDigit(bnDateOrCfg) : BanglaCalendar.isBanglaDateEn(bnDateOrCfg) ? bnDateOrCfg : monthDate;
417
+ if (BanglaCalendar.isBanglaDateString(dateBnYrOrCfg)) {
418
+ const parts = dateBnYrOrCfg.replace(/['"]/g, "").split("-");
419
+ bnYear = require_convert.banglaToDigit(parts[0]);
420
+ bnMonth = require_convert.banglaToDigit(parts[1]);
421
+ bnDate = require_convert.banglaToDigit(parts[2]);
422
+ }
423
+ const { gregYear } = this.#processGregYear(bnYear, bnMonth);
424
+ const { bnMonthTable } = this.#getBnMonthTableLeap(gregYear, bnYear);
425
+ const monthRange = bnMonthTable[bnMonth - 1];
426
+ if (bnDate > monthRange) {
427
+ bnDate -= monthRange;
428
+ if (bnMonth === 12) {
429
+ bnMonth = 1;
430
+ bnYear += 1;
431
+ } else bnMonth += 1;
432
+ }
433
+ this.year = {
434
+ bn: require_convert.digitToBangla(bnYear),
435
+ en: bnYear
436
+ };
437
+ this.month = {
438
+ bn: require_convert.digitToBangla(bnMonth),
439
+ en: bnMonth
440
+ };
441
+ this.date = {
442
+ bn: require_convert.digitToBangla(bnDate),
443
+ en: bnDate
444
+ };
445
+ const { gy, gm, gd, wd } = _extractDateUnits(this.toDate());
446
+ this.gregorian = {
447
+ year: gy,
448
+ month: gm,
449
+ date: gd
450
+ };
451
+ this.weekDay = wd;
452
+ this.isoWeekDay = wd === 0 ? 7 : wd;
453
+ }
454
+ [Symbol.toPrimitive](hint) {
455
+ if (hint === "number") return this.valueOf();
456
+ return this.toJSON();
457
+ }
458
+ get [Symbol.toStringTag]() {
459
+ return this.toJSON();
460
+ }
461
+ /**
462
+ * @instance Get timestamp in milliseconds for the current date.
463
+ * @remarks
464
+ * - Converts the current Bangla date to a Gregorian {@link Date} using {@link toDate()}.
465
+ * - Returns the Unix timestamp (in milliseconds) of the converted date.
466
+ * - The time component is normalized to midnight UTC during the conversion process.
467
+ */
468
+ valueOf() {
469
+ return this.toDate().getTime();
470
+ }
471
+ /**
472
+ * @instance Returns a string representation of the Bangla date in ISO-like format (YYYY-MM-DD with Bangla digits).
473
+ *
474
+ * @returns Bangla date string in the format: "YYYY-MM-DD" (e.g., "১৪৩০-০১-০১")
475
+ *
476
+ * @example
477
+ * const bnCal = new BanglaCalendar('2023-04-14');
478
+ * console.log(bnCal.toJSON()); // "১৪৩০-০১-০১"
479
+ *
480
+ * @remarks
481
+ * - This method is automatically called by {@link JSON.stringify()} method
482
+ * - Output follows the pattern: `"বছর-মাস-দিন"` with zero-padded Bangla digits
483
+ * - Month and date are padded to 2 digits, year to 4 digits
484
+ */
485
+ toJSON() {
486
+ const { year, month, date } = this;
487
+ return `${_padShunno(year.bn, 4)}-${_padShunno(month.bn)}-${_padShunno(date.bn)}`;
488
+ }
489
+ /**
490
+ * * Checks if the current Bangla year is a leap year.
491
+ *
492
+ * @returns `true` if the year is a leap year, `false` otherwise
493
+ *
494
+ * @example
495
+ * const date = new BanglaCalendar(1430, 1, 1);
496
+ * const isLeap = date.isLeapYear(); // false
497
+ *
498
+ * @remarks
499
+ * - Leap year determination depends on the selected calendar variant.
500
+ * - The `'revised-2019'` and `'revised-1966'` variants have different leap year rules.
501
+ * - **Revised-2019**: Leap year is determined by the associated Gregorian year's leap rule:
502
+ * - A year is a leap year if it is divisible by 4, but not divisible by 100, unless it is also divisible by 400.
503
+ * - **Revised-1966**: Leap year is determined solely by the Bangla year (`bnYear % 4 === 2`), no Gregorian rule applies.
504
+ */
505
+ isLeapYear() {
506
+ const { gregYear } = this.#processGregYear();
507
+ return this.#getBnMonthTableLeap(gregYear).isBnLeapYear;
508
+ }
509
+ /**
510
+ * * Converts the Bangla calendar date to a JS {@link Date} object.
511
+ *
512
+ * @returns Gregorian Date object equivalent to the Bangla date
513
+ *
514
+ * @example
515
+ * const bnDate = new BanglaCalendar('১৪৩০', '১', '১');
516
+ * const gregorianDate = bnDate.toDate(); // Date for April 14, 2023
517
+ * console.log(gregorianDate.toISOString()); // 2023-04-14T00:00:00.000Z
518
+ *
519
+ * @remarks
520
+ * - The conversion takes into account the calendar variant and leap year rules.
521
+ * - Time component is always set to `00:00:00` in UTC.
522
+ */
523
+ toDate() {
524
+ const { baseGregYear, gregYear } = this.#processGregYear();
525
+ const { bnMonthTable } = this.#getBnMonthTableLeap(gregYear);
526
+ const epoch = Date.UTC(baseGregYear, 3, 13);
527
+ let days = this.date.en;
528
+ for (let i = 0; i < this.month.en - 1; i++) days += bnMonthTable[i];
529
+ return new Date(days * MS_PER_DAY + epoch);
530
+ }
531
+ /**
532
+ * @instance Gets the Bangla season name for the current date.
533
+ *
534
+ * @param locale - Output locale ('bn' for Bengali, 'en' for English)
535
+ * @returns Name of the season in the specified locale
536
+ *
537
+ * @example
538
+ * const bnCal = new BanglaCalendar('2023-04-14');
539
+ * bnCal.getSeasonName(); // Returns: 'গ্রীষ্ম'
540
+ * bnCal.getSeasonName('en'); // Returns: 'Grisma (Summer)'
541
+ *
542
+ * @remarks
543
+ * Bangla calendar is traditionally divided into 6 seasons (ঋতু):
544
+ * - গ্রীষ্ম (Summer): Mid-April to Mid-June
545
+ * - বর্ষা (Monsoon): Mid-June to Mid-August
546
+ * - শরৎ (Autumn): Mid-August to Mid-October
547
+ * - হেমন্ত (Late Autumn): Mid-October to Mid-December
548
+ * - শীত (Winter): Mid-December to Mid-February
549
+ * - বসন্ত (Spring): Mid-February to Mid-April
550
+ */
551
+ getSeasonName(locale) {
552
+ return _getBnSeason(this.month.en - 1, locale);
553
+ }
554
+ /**
555
+ * @instance Gets the Bangla name of the month for the current date.
556
+ *
557
+ * @param locale - Output locale ('bn' for Bengali, 'en' for English)
558
+ * @returns Name of the month in the specified locale
559
+ *
560
+ * @example
561
+ * const bnCal = new BanglaCalendar('2023-04-14');
562
+ * bnCal.getMonthName(); // Returns: 'বৈশাখ'
563
+ * bnCal.getMonthName('en'); // Returns: 'Boishakh'
564
+ *
565
+ * @remarks
566
+ * - Month names follow traditional Bengali naming conventions.
567
+ * - English names are transliterated versions of the Bengali names.
568
+ * - Month determination may vary slightly between calendar variants near month boundaries.
569
+ */
570
+ getMonthName(locale) {
571
+ const MONTH = BN_MONTHS[this.month.en - 1];
572
+ return locale === "en" ? MONTH.en : MONTH.bn;
573
+ }
574
+ /**
575
+ * @instance Gets the Bangla name of the weekday for the current date.
576
+ *
577
+ * @param locale - Output locale ('bn' for Bengali, 'en' for English)
578
+ * @returns Name of the weekday in the specified locale
579
+ *
580
+ * @example
581
+ * const bnCal = new BanglaCalendar('2023-04-14'); // Friday
582
+ * bnCal.getDayName(); // Returns: 'শুক্রবার'
583
+ * bnCal.getDayName('en'); // Returns: 'Shukrobar (Friday)'
584
+ *
585
+ * @remarks
586
+ * - Weekday names follow the standard Bengali naming convention ending with 'বার'.
587
+ * - English names are the Latin transliterations of the Bangla names with standard English weekday names.
588
+ */
589
+ getDayName(locale) {
590
+ const DAY = BN_DAYS[this.weekDay];
591
+ return locale === "en" ? DAY.en : DAY.bn;
592
+ }
593
+ /**
594
+ * @instance Adds days to the current Bangla date.
595
+ *
596
+ * @param days - Number of days to add (can be negative to subtract days)
597
+ * @returns New `BanglaCalendar` instance with the adjusted date
598
+ *
599
+ * @example
600
+ * const bnCal = new BanglaCalendar('১৪৩০', '১', '১'); // ১ বৈশাখ ১৪৩০
601
+ *
602
+ * // Add days
603
+ * bnCal.addDays(7); // Returns: ৮ বৈশাখ ১৪৩০
604
+ *
605
+ * // Subtract days
606
+ * bnCal.addDays(-3); // Returns: ২৮ চৈত্র ১৪২৯
607
+ *
608
+ * // Add days crossing month boundary
609
+ * bnCal.addDays(35); // Returns: ৫ জ্যৈষ্ঠ ১৪৩০
610
+ *
611
+ * // Add days crossing year boundary
612
+ * const lateDate = new BanglaCalendar('১৪৩০', '১২', '২৫');
613
+ * lateDate.addDays(10); // Returns: ৫ বৈশাখ ১৪৩১
614
+ *
615
+ * @remarks
616
+ * - The resulting instance preserves the calendar variant of the original
617
+ * - Handles month and year transitions automatically
618
+ * - Accounts for varying month lengths and leap years
619
+ * - Time component remains at midnight UTC in the Gregorian conversion (using {@link BanglaCalendar.toDate()} method)
620
+ * - Negative values subtract days from the current date
621
+ */
622
+ addDays(days) {
623
+ const date = this.toDate();
624
+ return new BanglaCalendar(date.setDate(date.getDate() + days), { variant: this.variant });
625
+ }
626
+ /**
627
+ * @instance Adds weeks to the current Bangla date.
628
+ *
629
+ * @param weeks - Number of weeks to add (can be negative to subtract weeks)
630
+ * @returns New `BanglaCalendar` instance with the adjusted date
631
+ *
632
+ * @example
633
+ * const bnCal = new BanglaCalendar('১৪৩০', '১', '১'); // ১ বৈশাখ ১৪৩০
634
+ *
635
+ * // Add weeks
636
+ * bnCal.addWeeks(2); // Returns: ১৫ বৈশাখ ১৪৩০
637
+ *
638
+ * // Subtract weeks
639
+ * bnCal.addWeeks(-1); // Returns: ২৪ চৈত্র ১৪২৯
640
+ *
641
+ * // Add weeks crossing month boundary
642
+ * bnCal.addWeeks(5); // Returns: ৫ জ্যৈষ্ঠ ১৪৩০
643
+ *
644
+ * @remarks
645
+ * - Each week is treated as 7 days
646
+ * - The resulting instance preserves the calendar variant of the original
647
+ * - Handles month and year transitions automatically
648
+ * - Time component remains at midnight UTC in the Gregorian conversion (using {@link BanglaCalendar.toDate()} method)
649
+ * - Negative values subtract weeks from the current date
650
+ * - Useful for scheduling recurring weekly events
651
+ */
652
+ addWeeks(weeks) {
653
+ const date = this.toDate();
654
+ return new BanglaCalendar(date.setDate(date.getDate() + weeks * 7), { variant: this.variant });
655
+ }
656
+ /**
657
+ * @instance Adds months to the current Bangla date.
658
+ *
659
+ * @param months - Number of months to add (can be negative to subtract months)
660
+ * @param overflow - If `true`, allows date overflow to next month when day doesn't exist;
661
+ * if `false`, clamps to last day of target month (default: `true`)
662
+ * @returns New `BanglaCalendar` instance with the adjusted date
663
+ *
664
+ * @example
665
+ * // Normal case: day exists in target month
666
+ * const normal = new BanglaCalendar('১৪৩০', '২', '১৫');
667
+ * normal.addMonths(1); // Returns: ১৫ আষাঢ় ১৪৩০
668
+ * normal.addMonths(1, false); // Returns: ১৫ আষাঢ় ১৪৩০ (same behavior for both)
669
+ *
670
+ * // Edge case: day does not exist in target month
671
+ * const edgeCase = new BanglaCalendar('১৪৩০', '৬', '৩১'); // ৩১ আশ্বিন ১৪৩০
672
+ *
673
+ * // With overflow (default): 31st doesn't exist in কার্তিক (30 days)
674
+ * edgeCase.addMonths(1); // Returns: ১ অগ্রহায়ণ ১৪৩০ (overflows to next month)
675
+ *
676
+ * // Without overflow: clamps to last day of target month
677
+ * edgeCase.addMonths(1, false); // Returns: ৩০ কার্তিক ১৪৩০ (clamped)
678
+ *
679
+ * // Subtract months
680
+ * edgeCase.addMonths(-1); // Returns: ১ আশ্বিন ১৪৩০
681
+ * edgeCase.addMonths(-1, false); // Returns: ৩১ ভাদ্র ১৪৩০
682
+ *
683
+ * @remarks
684
+ * - When `overflow=true` (default):
685
+ * Follows JavaScript {@link Date} behavior where invalid dates overflow to the next month (e.g., ৩১ আশ্বিন + 1 month → ১ অগ্রহায়ণ)
686
+ * - When `overflow=false`:
687
+ * Clamps to the last valid day of the target month (e.g., ৩১ আশ্বিন + 1 month → ৩০ কার্তিক)
688
+ * - The resulting instance preserves the calendar variant of the original
689
+ * - Handles year transitions automatically
690
+ * - Time component remains at midnight UTC in the Gregorian conversion (using {@link BanglaCalendar.toDate()} method)
691
+ * - Negative values subtract months from the current date
692
+ */
693
+ addMonths(months, overflow = true) {
694
+ if (overflow) {
695
+ const current = this.toDate();
696
+ return new BanglaCalendar(current.setMonth(current.getMonth() + months), { variant: this.variant });
697
+ } else {
698
+ const { variant, year, month, date } = this;
699
+ let targetMonth = month.en + months;
700
+ let targetYear = year.en;
701
+ while (targetMonth > 12) {
702
+ targetMonth -= 12;
703
+ targetYear += 1;
704
+ }
705
+ while (targetMonth < 1) {
706
+ targetMonth += 12;
707
+ targetYear -= 1;
708
+ }
709
+ return this.#getClampedBnCal(targetYear, targetMonth, date.en, variant);
710
+ }
711
+ }
712
+ /**
713
+ * @instance Adds years to the current Bangla date.
714
+ *
715
+ * @param years - Number of years to add (can be negative to subtract years)
716
+ * @param overflow - If `true`, allows date overflow when day doesn't exist in target year;
717
+ * if `false`, clamps to last valid day of month (default: `true`)
718
+ * @returns New `BanglaCalendar` instance with the adjusted date
719
+ *
720
+ * @example
721
+ * const bnCal = new BanglaCalendar('১৪৩০', '১', '১৫'); // ১৫ বৈশাখ ১৪৩০
722
+ *
723
+ * // Add years
724
+ * bnCal.addYears(1); // Returns: ১৫ বৈশাখ ১৪৩১
725
+ *
726
+ * // Subtract years
727
+ * bnCal.addYears(-1); // Returns: ১৫ বৈশাখ ১৪২৯
728
+ *
729
+ * // Multiple years
730
+ * bnCal.addYears(5); // Returns: ১৫ বৈশাখ ১৪৩৫
731
+ *
732
+ * // Edge case: day adjustment for ফাল্গুন (accounting leap year)
733
+ * const leapDay = new BanglaCalendar('১৪৩১', '১১', '৩০'); // ১৪৩১ is a leap year
734
+ * leapDay.addYears(1, false); // Returns: ২৯ ফাল্গুন ১৪৩২ (non-leap years have 29 days in ফাল্গুন)
735
+ *
736
+ * @remarks
737
+ * - The resulting instance preserves the calendar variant of the original
738
+ * - Negative values subtract years from the current date
739
+ * - Year addition follows Bangla calendar years
740
+ * - Time component remains at midnight UTC in the Gregorian conversion (using {@link BanglaCalendar.toDate()} method)
741
+ * - The month and day generally remain the same unless affected by leap year rules
742
+ */
743
+ addYears(years, overflow = true) {
744
+ const { variant, year, month, date } = this;
745
+ const targetYear = year.en + years;
746
+ if (overflow) return new BanglaCalendar(targetYear, month.en, date.en, { variant });
747
+ else return this.#getClampedBnCal(targetYear, month.en, date.en, variant);
748
+ }
749
+ /**
750
+ * @instance Gets a new `BanglaCalendar` instance representing the first day of the current month.
751
+ *
752
+ * @returns A `BanglaCalendar` instance set to the 1st day of the current month
753
+ *
754
+ * @example
755
+ * const bnCal = new BanglaCalendar('১৪৩০', '৫', '১৫');
756
+ * const startOfMonth = bnCal.startOfMonth(); // Returns: ১ জ্যৈষ্ঠ ১৪৩০
757
+ *
758
+ * @remarks
759
+ * - The resulting instance preserves the calendar variant of the original
760
+ * - Useful for date range calculations and month-based operations
761
+ * - Time component remains at midnight UTC in the Gregorian conversion (using {@link BanglaCalendar.toDate()} method)
762
+ */
763
+ startOfMonth() {
764
+ const { year, month, variant } = this;
765
+ return new BanglaCalendar(year.en, month.en, 1, { variant });
766
+ }
767
+ /**
768
+ * @instance Gets a new `BanglaCalendar` instance representing the last day of the current month.
769
+ *
770
+ * @returns A `BanglaCalendar` instance set to the last day of the current month
771
+ *
772
+ * @example
773
+ * const bnCal = new BanglaCalendar('১৪৩০', '৫', '১৫');
774
+ * const endOfMonth = bnCal.endOfMonth(); // Returns: ৩১ জ্যৈষ্ঠ ১৪৩০ (or 30 for some months)
775
+ *
776
+ * @remarks
777
+ * - The resulting instance preserves the calendar variant of the original
778
+ * - Accounts for month length variations (29/30/31 days) including leap years
779
+ * - Time component remains at midnight UTC in the Gregorian conversion (using {@link BanglaCalendar.toDate()} method)
780
+ */
781
+ endOfMonth() {
782
+ const { year, month, variant } = this;
783
+ return new BanglaCalendar(year.en, month.en, this.daysInMonth(), { variant });
784
+ }
785
+ /**
786
+ * @instance Gets a new `BanglaCalendar` instance representing the first day of the current year (১ বৈশাখ).
787
+ *
788
+ * @returns A `BanglaCalendar` instance set to ১ বৈশাখ of the current year
789
+ *
790
+ * @example
791
+ * const bnCal = new BanglaCalendar('১৪৩০', '৫', '১৫');
792
+ * const startOfYear = bnCal.startOfYear(); // Returns: ১ বৈশাখ ১৪৩০
793
+ *
794
+ * @remarks
795
+ * - The resulting instance preserves the calendar variant of the original
796
+ * - Always returns the 1st day of the 1st month (বৈশাখ)
797
+ * - Time component remains at midnight UTC in the Gregorian conversion (using {@link BanglaCalendar.toDate()} method)
798
+ */
799
+ startOfYear() {
800
+ const { year, variant } = this;
801
+ return new BanglaCalendar(year.en, 1, 1, { variant });
802
+ }
803
+ /**
804
+ * @instance Gets a new `BanglaCalendar` instance representing the last day of the current year (৩০ চৈত্র).
805
+ *
806
+ * @returns A `BanglaCalendar` instance set to ৩০ চৈত্র of the current year
807
+ *
808
+ * @example
809
+ * const bnCal = new BanglaCalendar('১৪৩০', '৫', '১৫');
810
+ * const endOfYear = bnCal.endOfYear(); // Returns: ৩০ চৈত্র ১৪৩০
811
+ *
812
+ * @remarks
813
+ * - The resulting instance preserves the calendar variant of the original
814
+ * - Always returns the 30th day of the 12th month (চৈত্র)
815
+ * - Time component remains at midnight UTC in the Gregorian conversion (using {@link BanglaCalendar.toDate()} method)
816
+ */
817
+ endOfYear() {
818
+ const { year, variant } = this;
819
+ return new BanglaCalendar(year.en, 12, 30, { variant });
820
+ }
821
+ /**
822
+ * @instance Gets the number of days in a Bangla month.
823
+ *
824
+ * @param month - Optional Bangla month (1-12 in Latin digits)
825
+ * @returns Number of days in the specified month (29, 30, or 31)
826
+ *
827
+ * @example
828
+ * const bnCal = new BanglaCalendar('১৪৩০', '১', '১');
829
+ *
830
+ * // Get days in current month
831
+ * bnCal.daysInMonth(); // Returns: 31 (বৈশাখ has 31 days)
832
+ *
833
+ * // Get days in specific month
834
+ * bnCal.daysInMonth(2); // Returns: 31 (জ্যৈষ্ঠ has 31 days)
835
+ * bnCal.daysInMonth(12); // Returns: 30 (চৈত্র has 30 days)
836
+ *
837
+ * @remarks
838
+ * - The method accounts for the selected calendar variant when determining leap years
839
+ * - If no month is provided, uses the current instance's month
840
+ * - In the 'revised-2019' variant, leap years follow Gregorian leap rules
841
+ * - In the 'revised-1966' variant, leap years occur when `bnYear % 4 === 2`
842
+ */
843
+ daysInMonth(month) {
844
+ const { gregYear } = this.#processGregYear();
845
+ const { bnMonthTable } = this.#getBnMonthTableLeap(gregYear);
846
+ return bnMonthTable[(month ?? this.month.en) - 1];
847
+ }
848
+ /**
849
+ * @instance Returns a string representation of the Bangla date in Bengali format.
850
+ *
851
+ * @returns Bangla date string in the format: "শুক্রবার, ১৫ জ্যৈষ্ঠ, ১৪৩০ [গ্রীষ্ম]"
852
+ *
853
+ * @example
854
+ * const bnCal = new BanglaCalendar('2023-04-14');
855
+ * console.log(bnCal.toString()); // "শুক্রবার, ১ বৈশাখ, ১৪৩০ [গ্রীষ্ম]"
856
+ *
857
+ * @remarks
858
+ * - Equivalent to calling {@link toStringEn()} with 'bn' locale
859
+ * - Format includes day name, date, month name, year, and season in brackets
860
+ * - Uses Bengali digits and Bengali month/day names
861
+ */
862
+ toString() {
863
+ return this.#toString("bn");
864
+ }
865
+ /**
866
+ * @instance Returns a string representation of the Bangla date in English/Latin format.
867
+ *
868
+ * @returns Bangla date string in the format: "Shukrobar (Friday), 15 Joishtho, 1430 [Grisma (Summer)]"
869
+ *
870
+ * @example
871
+ * const bnCal = new BanglaCalendar('2023-04-14');
872
+ * console.log(bnCal.toStringEn()); // "Shukrobar (Friday), 1 Boishakh, 1430 [Grisma (Summer)]"
873
+ *
874
+ * @remarks
875
+ * - Equivalent to calling {@link toString()} with 'en' locale
876
+ * - Format includes transliterated day name (with English equivalent), date, transliterated month and season name, and year.
877
+ * - Uses Latin digits and transliterated Bengali names
878
+ */
879
+ toStringEn() {
880
+ return this.#toString("en");
881
+ }
882
+ /**
883
+ * @instance Formats the current date as a Bangla calendar date string (no time) using customizable tokens.
884
+ *
885
+ * @param format - Format string using tokens (default: `'ddd, DD mmmm (SS), YYYY বঙ্গাব্দ'`)
886
+ * @returns Formatted Bangla date string according to the specified format
887
+ *
888
+ * @example
889
+ * const bnCal = new BanglaCalendar('2023-04-14');
890
+ *
891
+ * bnCal.format();
892
+ * // Returns: 'শুক্রবার, বৈশাখ ০১ (গ্রীষ্মকাল), ১৪৩০ বঙ্গাব্দ'
893
+ *
894
+ * bnCal.format('YYYY-MM-DD');
895
+ * // Returns: '১৪৩০-০১-০১'
896
+ *
897
+ * bnCal.format('mmmm DD, YYYY');
898
+ * // Returns: 'বৈশাখ ০১, ১৪৩০'
899
+ *
900
+ * @remarks
901
+ * - **Important:** Does not allow time formatting tokens!
902
+ * - Supported format tokens include: `YYYY`, `YY`, `mmmm`, `mmm`, `MM`, `M`, `DD`, `D`, `dd`, `ddd`, `Do`, `SS` and `S`.
903
+ * - **Year**: `YYYY/yyyy` (full year), `YY/yy` (last 2 digits)
904
+ * - **Month**: `M/MM`(padded), `mmm` (short name), `mmmm` (full name)
905
+ * - **Day**: `D/DD`(padded), Do (results same as cardinal for Bangla dates)
906
+ * - **Weekday**: `d` (short), `dd` (without 'বার'), `ddd` (full)
907
+ * - **Season**: `S` (season), `SS` (season with 'কাল' suffix)
908
+ * - To output raw text (i.e., not interpreted as a date token), wrap it in square brackets.
909
+ * - For example, `[আজ] ddd` results in `আজ রবিবার`, and `[year ]YYYY` results in `year ২০২৫`.
910
+ * - *Any token not wrapped in brackets will be parsed and replaced with its corresponding date component.*
911
+ */
912
+ format(format) {
913
+ const { year, month, date, weekDay } = this;
914
+ const seasonName = this.getSeasonName();
915
+ const M_NAME = BN_MONTHS[month.en - 1];
916
+ const D_NAME = BN_DAYS[weekDay];
917
+ const paddedYear = _padShunno(year.bn, 4);
918
+ const dateComponents = {
919
+ YYYY: paddedYear,
920
+ YY: paddedYear.slice(-2),
921
+ yyyy: paddedYear,
922
+ yy: paddedYear.slice(-2),
923
+ M: month.bn,
924
+ MM: _padShunno(month.bn),
925
+ mmm: M_NAME.short,
926
+ mmmm: M_NAME.bn,
927
+ d: D_NAME.short,
928
+ dd: D_NAME.bn.replace("বার", ""),
929
+ ddd: D_NAME.bn,
930
+ D: date.bn,
931
+ DD: _padShunno(date.bn),
932
+ Do: date.bn,
933
+ S: seasonName,
934
+ SS: seasonName + "কাল"
935
+ };
936
+ return _formatDateCore(format || "ddd, DD mmmm (SS), YYYY বঙ্গাব্দ", dateComponents);
937
+ }
938
+ /** Process Gregorian base year and calculated year from optional Bangla year and month */
939
+ #processGregYear(bnYear, bnMonth) {
940
+ const baseGregYear = (bnYear ?? this.year.en) + 593;
941
+ return {
942
+ baseGregYear,
943
+ gregYear: (bnMonth ?? this.month.en) > 10 ? baseGregYear + 1 : baseGregYear
944
+ };
945
+ }
946
+ /** Get the Bangla month table and leap year flag based on calendar variant */
947
+ #getBnMonthTableLeap(gregYear, bnYear) {
948
+ const isBnLeapYear = _isBnLeapYear(bnYear ?? this.year.en, gregYear, this.variant);
949
+ return {
950
+ bnMonthTable: isBnLeapYear ? BN_MONTH_TABLES?.[this.variant].leap : BN_MONTH_TABLES?.[this.variant].normal,
951
+ isBnLeapYear
952
+ };
953
+ }
954
+ /**
955
+ * @internal Get new `BanglaCalendar` instance with clamped date
956
+ * @param tyBn - Target Bangla year
957
+ * @param tmBn - Target Bangla month
958
+ * @param cdBn - Current Bangla date of the month
959
+ * @param variant - Calendar variant to preserve
960
+ * @returns New `BanglaCalendar` instance with date clamped to valid range
961
+ *
962
+ * @remarks
963
+ * - Clamps the date to not exceed the number of days in the target month
964
+ * - Used internally for non-overflow date arithmetic
965
+ * - Ensures dates like ৩১ don't become invalid in months with only 30 days
966
+ */
967
+ #getClampedBnCal(tyBn, tmBn, cdBn, variant) {
968
+ const { gregYear } = this.#processGregYear(tyBn, tmBn);
969
+ const { bnMonthTable } = this.#getBnMonthTableLeap(gregYear, tyBn);
970
+ return new BanglaCalendar(tyBn, tmBn, Math.min(cdBn, bnMonthTable[tmBn - 1]), { variant });
971
+ }
972
+ /** Process variant from the config */
973
+ #processVariants(v1, v2, v3, v4) {
974
+ return this.$hasVariantConfig(v1) ? v1.variant : this.$hasVariantConfig(v2) ? v2.variant : this.$hasVariantConfig(v3) ? v3.variant : this.$hasVariantConfig(v4) ? v4.variant : "revised-2019";
975
+ }
976
+ /** Process {@link Date} and extract Bangla year, month and dates in both Bangla and Latin */
977
+ #processDate(date) {
978
+ const bnYear = _getBnYear(date);
979
+ const { days, monthIdx } = _bnDaysMonthIdx(date, this.variant);
980
+ return {
981
+ year: bnYear,
982
+ month: monthIdx + 1,
983
+ monthDate: days + 1
984
+ };
985
+ }
986
+ /** Convert to human readable string either in `bn` or `en` locale */
987
+ #toString(lcl = "bn") {
988
+ const { year, date } = this;
989
+ return `${this.getDayName(lcl)}, ${date[lcl]} ${this.getMonthName(lcl)}, ${year[lcl]} [${this.getSeasonName(lcl)}]`;
990
+ }
991
+ /**
992
+ * @static Check if a value is a configuration object that contains a valid {@link variant}
993
+ * @param value Value to check
994
+ * @returns `true` if the value contains a valid {@link variant} property, `false` otherwise
995
+ */
996
+ $hasVariantConfig(value) {
997
+ return require_convert.isObjectWithKeys(value, ["variant"]) && require_convert.isNonEmptyString(value.variant) && (value.variant === "revised-1966" || value.variant === "revised-2019");
998
+ }
999
+ /**
1000
+ * @static Checks whether a value is a valid Bangla year in Bangla digits (`০–৯৯৯৯`).
1001
+ *
1002
+ * @param value - Value to check. Accepts both zero-padded and non-padded Bangla digits
1003
+ * @returns `true` if the value is a valid Bangla year, `false` otherwise
1004
+ *
1005
+ * @example
1006
+ * BanglaCalendar.isBanglaYear('১৪৩০'); // true
1007
+ * BanglaCalendar.isBanglaYear('০'); // true
1008
+ * BanglaCalendar.isBanglaYear('১০০০০'); // false (too many digits)
1009
+ * BanglaCalendar.isBanglaYear('1430'); // false (Latin digits)
1010
+ */
1011
+ static isBanglaYear(value) {
1012
+ return require_convert.isNonEmptyString(value) && /^(?:০{0,3}[১-৯][০-৯]{0,3}|০)$/.test(value.trim());
1013
+ }
1014
+ /**
1015
+ * @static Checks whether a value is a valid Bangla year in Latin digits (`0–9999`).
1016
+ *
1017
+ * @param value - Value to check (must be a number)
1018
+ * @returns `true` if the value is a valid Bangla year, `false` otherwise
1019
+ *
1020
+ * @example
1021
+ * BanglaCalendar.isBanglaYearEn(1430); // true
1022
+ * BanglaCalendar.isBanglaYearEn(0); // true
1023
+ * BanglaCalendar.isBanglaYearEn(10000); // false
1024
+ * BanglaCalendar.isBanglaYearEn(-1); // false
1025
+ */
1026
+ static isBanglaYearEn(value) {
1027
+ return require_convert.isInteger(value) && value >= 0 && value <= 9999;
1028
+ }
1029
+ /**
1030
+ * @static Checks whether a value is a valid Bangla month in Bangla digits (`১–১২`).
1031
+ *
1032
+ * @param value - Value to check. Accepts both zero-padded and non-padded Bangla digits
1033
+ * @returns `true` if the value is a valid Bangla month, `false` otherwise
1034
+ *
1035
+ * @example
1036
+ * BanglaCalendar.isBanglaMonth('১'); // true
1037
+ * BanglaCalendar.isBanglaMonth('১২'); // true
1038
+ * BanglaCalendar.isBanglaMonth('১৩'); // false
1039
+ * BanglaCalendar.isBanglaMonth('0'); // false (Latin digit)
1040
+ */
1041
+ static isBanglaMonth(value) {
1042
+ return require_convert.isNonEmptyString(value) && /^(?:০?[১-৯]|১০|১১|১২)$/.test(value.trim());
1043
+ }
1044
+ /**
1045
+ * @static Checks whether a value is a valid Bangla month in Latin digits (`1–12`).
1046
+ *
1047
+ * @param value - Value to check
1048
+ * @returns `true` if the value is a valid Bangla month, `false` otherwise
1049
+ *
1050
+ * @example
1051
+ * BanglaCalendar.isBanglaMonthEn(1); // true
1052
+ * BanglaCalendar.isBanglaMonthEn(12); // true
1053
+ * BanglaCalendar.isBanglaMonthEn(0); // false
1054
+ * BanglaCalendar.isBanglaMonthEn(13); // false
1055
+ */
1056
+ static isBanglaMonthEn(value) {
1057
+ return require_convert.isInteger(value) && value >= 1 && value <= 12;
1058
+ }
1059
+ /**
1060
+ * @static Checks whether a value is a valid Bangla date of month in Bangla digits (`১–৩১`).
1061
+ *
1062
+ * @param value - Value to check. Accepts both zero-padded and non-padded Bangla digits
1063
+ * @returns `true` if the value is a valid Bangla date, `false` otherwise
1064
+ *
1065
+ * @example
1066
+ * BanglaCalendar.isBanglaDate('১'); // true
1067
+ * BanglaCalendar.isBanglaDate('৩১'); // true
1068
+ * BanglaCalendar.isBanglaDate('৩২'); // false
1069
+ * BanglaCalendar.isBanglaDate('০'); // false
1070
+ */
1071
+ static isBanglaDate(value) {
1072
+ return require_convert.isNonEmptyString(value) && /^(?:০?[১-৯]|[১২][০-৯]|৩০|৩১)$/.test(value.trim());
1073
+ }
1074
+ /**
1075
+ * @static Checks whether a value is a valid Bangla date of month in Latin digits (`1–31`).
1076
+ *
1077
+ * @param value - Value to check
1078
+ * @returns `true` if the value is a valid Bangla date, `false` otherwise
1079
+ *
1080
+ * @example
1081
+ * BanglaCalendar.isBanglaDateEn(1); // true
1082
+ * BanglaCalendar.isBanglaDateEn(31); // true
1083
+ * BanglaCalendar.isBanglaDateEn(32); // false
1084
+ * BanglaCalendar.isBanglaDateEn(0); // false
1085
+ */
1086
+ static isBanglaDateEn(value) {
1087
+ return require_convert.isInteger(value) && value >= 1 && value <= 31;
1088
+ }
1089
+ /**
1090
+ * @static Checks whether a string follows the Bangla date format pattern (`YYYY-MM-DD` with Bangla digits).
1091
+ *
1092
+ * @param value - String value to check
1093
+ * @returns `true` if the string matches the pattern `"বছর-মাস-দিন"` with Bangla digits, `false` otherwise
1094
+ *
1095
+ * @example
1096
+ * BanglaCalendar.isBanglaDateString('১৪৩০-০১-০১'); // true
1097
+ * BanglaCalendar.isBanglaDateString('1430-01-01'); // false (Latin digits)
1098
+ * BanglaCalendar.isBanglaDateString('১৪৩০-১-১'); // true (single-digit month/date)
1099
+ * BanglaCalendar.isBanglaDateString('১৪৩০-১৩-০১'); // false (invalid month)
1100
+ *
1101
+ * @remarks
1102
+ * - Accepts both zero-padded and non-padded Bangla digits
1103
+ * - Validates year, month, and date components separately
1104
+ * - Year must be `‌০-৯৯৯৯`, month must be `১-১২`, date must be `১-৩১`
1105
+ */
1106
+ static isBanglaDateString(value) {
1107
+ if (require_convert.isNonEmptyString(value) && value.includes("-")) {
1108
+ const [year, month, date] = value.replace(/['"]/g, "").split("-");
1109
+ return BanglaCalendar.isBanglaYear(year) && BanglaCalendar.isBanglaMonth(month) && BanglaCalendar.isBanglaDate(date);
1110
+ }
1111
+ return false;
1112
+ }
1113
+ };
1114
+
1115
+ //#endregion
1116
+ exports.BanglaCalendar = BanglaCalendar;
1117
+ exports.BnCalendar = BanglaCalendar;
1118
+ exports.Bongabdo = BanglaCalendar;