nepali-date-library 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 +128 -0
- package/dist/Helper/Constants.d.ts +16 -0
- package/dist/Helper/DateConverter.d.ts +12 -0
- package/dist/Helper/DateFormatter.d.ts +2 -0
- package/dist/NepaliDate.d.ts +272 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +1 -0
- package/package.json +25 -0
- package/src/Helper/Constants.ts +132 -0
- package/src/Helper/DateConverter.ts +47 -0
- package/src/Helper/DateFormatter.ts +170 -0
- package/src/NepaliDate.ts +680 -0
- package/src/index.ts +5 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
import { EPOCH, MONTH_EN, MONTH_NP, MONTH_SHORT_EN, MONTH_SHORT_NP, NEPALI_DATE_MAP, WEEK_EN, WEEK_NP, WEEK_SHORT_EN, WEEK_SHORT_NP } from './Helper/Constants';
|
|
2
|
+
import format from './Helper/DateFormatter';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parses a date string into Nepali date components
|
|
6
|
+
* @param dateString Date string in format YYYY-MM-DD, YYYY/MM/DD, or YYYY.MM.DD
|
|
7
|
+
* @returns Tuple containing [year, month, day] where month is 0-indexed
|
|
8
|
+
* @throws Error if the date format is invalid or date is out of range
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
function _parse(dateString: string): [number, number, number] {
|
|
12
|
+
const parts = dateString.split(/[-./]/, 3);
|
|
13
|
+
|
|
14
|
+
const [year, month = 0, day = 1] = parts.map(d => {
|
|
15
|
+
const n = parseInt(d, 10);
|
|
16
|
+
if (Number.isNaN(n)) {
|
|
17
|
+
throw new Error('Invalid date');
|
|
18
|
+
}
|
|
19
|
+
return n;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (year < NEPALI_DATE_MAP[0].year || year >= NEPALI_DATE_MAP[0].year + NEPALI_DATE_MAP.length) {
|
|
23
|
+
throw new Error('Nepal year out of range');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (month < 0 || month > 11) {
|
|
27
|
+
throw new Error('Invalid nepali month must be between 0 - 11');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const daysInMonth = NEPALI_DATE_MAP[year - NEPALI_DATE_MAP[0].year].days[month - 1]
|
|
31
|
+
if (day < 1 || day > daysInMonth) {
|
|
32
|
+
throw new Error(`Invalid nepali date must be between 1 - ${daysInMonth} in ${year} ${month}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return [year, month - 1, day];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Class representing a Nepali date (Bikram Sambat)
|
|
40
|
+
* Provides methods to create, manipulate and format Nepali dates
|
|
41
|
+
*/
|
|
42
|
+
export class NepaliDate {
|
|
43
|
+
/** JavaScript Date object representing the equivalent Gregorian date */
|
|
44
|
+
public timestamp!: Date;
|
|
45
|
+
|
|
46
|
+
/** Nepali year (BS) */
|
|
47
|
+
public year!: number;
|
|
48
|
+
|
|
49
|
+
/** Nepali month (0-11) */
|
|
50
|
+
public month!: number;
|
|
51
|
+
|
|
52
|
+
/** Nepali day of month (1-32) */
|
|
53
|
+
public day!: number;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Creates a NepaliDate instance for the current date
|
|
57
|
+
*/
|
|
58
|
+
constructor();
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Creates a NepaliDate instance from various input types
|
|
62
|
+
* @param date Source date as Date, NepaliDate, timestamp number, or date string
|
|
63
|
+
*/
|
|
64
|
+
constructor(date: Date | NepaliDate | number | string);
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Creates a NepaliDate instance with the specified year, month, and day
|
|
68
|
+
* @param year Nepali year
|
|
69
|
+
* @param month Nepali month (0-11)
|
|
70
|
+
* @param day Nepali day (1-32)
|
|
71
|
+
*/
|
|
72
|
+
constructor(year: number, month: number, day: number);
|
|
73
|
+
constructor(...args: any[]) {
|
|
74
|
+
if (args.length === 0) {
|
|
75
|
+
this.setEnglishDate(new Date());
|
|
76
|
+
} else if (args.length === 1) {
|
|
77
|
+
const e = args[0];
|
|
78
|
+
if (typeof e === 'object') {
|
|
79
|
+
if (e instanceof Date) {
|
|
80
|
+
this.setEnglishDate(e);
|
|
81
|
+
} else if (e instanceof NepaliDate) {
|
|
82
|
+
this.timestamp = e.timestamp;
|
|
83
|
+
this.year = e.year;
|
|
84
|
+
this.month = e.month;
|
|
85
|
+
this.day = e.day;
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error('Invalid date argument');
|
|
88
|
+
}
|
|
89
|
+
} else if (typeof e === 'string') {
|
|
90
|
+
this.set(..._parse(e));
|
|
91
|
+
} else if (typeof e === 'number') {
|
|
92
|
+
this.setEnglishDate(new Date(e));
|
|
93
|
+
} else {
|
|
94
|
+
throw new Error('Invalid date argument');
|
|
95
|
+
}
|
|
96
|
+
} else if (args.length === 3) {
|
|
97
|
+
this.set(args[0], args[1], args[2]);
|
|
98
|
+
} else {
|
|
99
|
+
throw new Error('Invalid argument syntax');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Sets the internal properties based on the provided English (Gregorian) date
|
|
105
|
+
* @param date JavaScript Date object
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
private setEnglishDate(date: Date): void {
|
|
109
|
+
this.timestamp = date;
|
|
110
|
+
let daysCount = Math.floor((this.timestamp.getTime() - EPOCH) / 86400000);
|
|
111
|
+
let idx = Math.floor(daysCount / 366);
|
|
112
|
+
|
|
113
|
+
while (daysCount >= NEPALI_DATE_MAP[idx].daysTillNow) {
|
|
114
|
+
idx += 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let prevTillNow = NEPALI_DATE_MAP[idx - 1] ? NEPALI_DATE_MAP[idx - 1].daysTillNow : 0;
|
|
118
|
+
|
|
119
|
+
daysCount -= prevTillNow;
|
|
120
|
+
const tmp = NEPALI_DATE_MAP[idx];
|
|
121
|
+
|
|
122
|
+
this.year = tmp.year;
|
|
123
|
+
this.month = 0;
|
|
124
|
+
|
|
125
|
+
while (daysCount >= tmp.days[this.month]) {
|
|
126
|
+
this.month += 1;
|
|
127
|
+
daysCount -= tmp.days[this.month - 1];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this.day = daysCount + 1;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Returns the equivalent English (Gregorian) date
|
|
135
|
+
* @returns JavaScript Date object representing the equivalent Gregorian date
|
|
136
|
+
*/
|
|
137
|
+
public getEnglishDate(): Date {
|
|
138
|
+
return this.timestamp;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Parses a date string and updates the current instance
|
|
143
|
+
* @param dateString Date string in format YYYY-MM-DD, YYYY/MM/DD, or YYYY.MM.DD
|
|
144
|
+
* @throws Error if the date format is invalid or date is out of range
|
|
145
|
+
*/
|
|
146
|
+
public parse(dateString: string): void {
|
|
147
|
+
this.set(..._parse(dateString));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Returns the Nepali year
|
|
152
|
+
* @returns Nepali year
|
|
153
|
+
*/
|
|
154
|
+
public getYear(): number {
|
|
155
|
+
return this.year;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Returns the Nepali month (0-11)
|
|
160
|
+
* @returns Nepali month (0-11)
|
|
161
|
+
*/
|
|
162
|
+
public getMonth(): number {
|
|
163
|
+
return this.month;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Returns the Nepali day of month
|
|
168
|
+
* @returns Nepali day of month (1-32)
|
|
169
|
+
*/
|
|
170
|
+
public getDate(): number {
|
|
171
|
+
return this.day;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Returns the day of week (0-6, 0 = Sunday)
|
|
176
|
+
* @returns Day of week (0-6, 0 = Sunday)
|
|
177
|
+
*/
|
|
178
|
+
public getDay(): number {
|
|
179
|
+
return this.timestamp.getDay();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Returns the hour (0-23)
|
|
184
|
+
* @returns Hour (0-23)
|
|
185
|
+
*/
|
|
186
|
+
public getHours(): number {
|
|
187
|
+
return this.timestamp.getHours();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Returns the minutes (0-59)
|
|
192
|
+
* @returns Minutes (0-59)
|
|
193
|
+
*/
|
|
194
|
+
public getMinutes(): number {
|
|
195
|
+
return this.timestamp.getMinutes();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Returns the seconds (0-59)
|
|
200
|
+
* @returns Seconds (0-59)
|
|
201
|
+
*/
|
|
202
|
+
public getSeconds(): number {
|
|
203
|
+
return this.timestamp.getSeconds();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Returns the milliseconds (0-999)
|
|
208
|
+
* @returns Milliseconds (0-999)
|
|
209
|
+
*/
|
|
210
|
+
public getMilliseconds(): number {
|
|
211
|
+
return this.timestamp.getMilliseconds();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Returns the timestamp (milliseconds since Unix Epoch)
|
|
216
|
+
* @returns Timestamp in milliseconds
|
|
217
|
+
*/
|
|
218
|
+
public getTime(): number {
|
|
219
|
+
return this.timestamp.getTime();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Sets the Nepali year
|
|
224
|
+
* @param year Nepali year
|
|
225
|
+
*/
|
|
226
|
+
public setYear(year: number): void {
|
|
227
|
+
this.set(year, this.month, this.day);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Sets the Nepali month
|
|
232
|
+
* @param month Nepali month (0-11)
|
|
233
|
+
*/
|
|
234
|
+
public setMonth(month: number): void {
|
|
235
|
+
this.set(this.year, month, this.day);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Sets the Nepali day of month
|
|
240
|
+
* @param day Nepali day of month (1-32)
|
|
241
|
+
*/
|
|
242
|
+
public setDate(day: number): void {
|
|
243
|
+
this.set(this.year, this.month, day);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Sets the Nepali date components and updates the internal timestamp
|
|
248
|
+
* @param year Nepali year
|
|
249
|
+
* @param month Nepali month (0-11)
|
|
250
|
+
* @param date Nepali day (1-32)
|
|
251
|
+
*/
|
|
252
|
+
public set(year: number, month: number, date: number): void {
|
|
253
|
+
const idx = year + Math.floor(month / 12) - NEPALI_DATE_MAP[0].year;
|
|
254
|
+
const tmp = NEPALI_DATE_MAP[idx];
|
|
255
|
+
let d = tmp.daysTillNow - tmp.totalDays;
|
|
256
|
+
|
|
257
|
+
const m = month % 12;
|
|
258
|
+
const mm = m < 0 ? 12 + m : m;
|
|
259
|
+
|
|
260
|
+
for (let i = 0; i < mm; i += 1) {
|
|
261
|
+
d += tmp.days[i];
|
|
262
|
+
}
|
|
263
|
+
d += date - 1;
|
|
264
|
+
this.setEnglishDate(new Date(EPOCH + d * 86400000));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Formats the Nepali date according to the specified format string
|
|
269
|
+
* @param formatStr Format string (see DateFormatter for syntax)
|
|
270
|
+
* @returns Formatted date string
|
|
271
|
+
*/
|
|
272
|
+
public format(formatStr: string): string {
|
|
273
|
+
return format(this, formatStr);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Returns the string representation of the Nepali date
|
|
278
|
+
* @returns Date string in format YYYY/MM/DD where MM is 1-indexed
|
|
279
|
+
*/
|
|
280
|
+
public toString(): string {
|
|
281
|
+
return `${this.year}/${this.month + 1}/${this.day}`;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Adds the specified number of days to the current Nepali date
|
|
286
|
+
* @param days Number of days to add (can be negative)
|
|
287
|
+
* @returns A new NepaliDate instance with the added days
|
|
288
|
+
*/
|
|
289
|
+
public addDays(days: number): NepaliDate {
|
|
290
|
+
const newTimestamp = new Date(this.timestamp.getTime() + days * 86400000);
|
|
291
|
+
return new NepaliDate(newTimestamp);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Adds the specified number of months to the current Nepali date
|
|
296
|
+
* @param months Number of months to add (can be negative)
|
|
297
|
+
* @returns A new NepaliDate instance with the added months
|
|
298
|
+
*/
|
|
299
|
+
public addMonths(months: number): NepaliDate {
|
|
300
|
+
let newYear = this.year;
|
|
301
|
+
let newMonth = this.month + months;
|
|
302
|
+
|
|
303
|
+
newYear += Math.floor(newMonth / 12);
|
|
304
|
+
newMonth = newMonth % 12;
|
|
305
|
+
|
|
306
|
+
if (newMonth < 0) {
|
|
307
|
+
newMonth += 12;
|
|
308
|
+
newYear -= 1;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const yearIndex = newYear - NEPALI_DATE_MAP[0].year;
|
|
312
|
+
if (yearIndex < 0 || yearIndex >= NEPALI_DATE_MAP.length) {
|
|
313
|
+
throw new Error('Resulting date is out of supported range');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const daysInNewMonth = NEPALI_DATE_MAP[yearIndex].days[newMonth];
|
|
317
|
+
|
|
318
|
+
const newDay = Math.min(this.day, daysInNewMonth);
|
|
319
|
+
|
|
320
|
+
return new NepaliDate(newYear, newMonth, newDay);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Adds the specified number of years to the current Nepali date
|
|
325
|
+
* @param years Number of years to add (can be negative)
|
|
326
|
+
* @returns A new NepaliDate instance with the added years
|
|
327
|
+
*/
|
|
328
|
+
public addYears(years: number): NepaliDate {
|
|
329
|
+
const newYear = this.year + years;
|
|
330
|
+
|
|
331
|
+
if (newYear < NEPALI_DATE_MAP[0].year ||
|
|
332
|
+
newYear >= NEPALI_DATE_MAP[0].year + NEPALI_DATE_MAP.length) {
|
|
333
|
+
throw new Error('Resulting date is out of supported range');
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const yearIndex = newYear - NEPALI_DATE_MAP[0].year;
|
|
337
|
+
|
|
338
|
+
if (this.month === 11 && this.day === 29) {
|
|
339
|
+
const daysInFalgun = NEPALI_DATE_MAP[yearIndex].days[11];
|
|
340
|
+
if (daysInFalgun < 29) {
|
|
341
|
+
return new NepaliDate(newYear, 11, daysInFalgun);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return new NepaliDate(newYear, this.month, this.day);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Returns the earliest date supported by the NepaliDate class
|
|
350
|
+
* @returns JavaScript Date object representing the minimum supported date
|
|
351
|
+
*/
|
|
352
|
+
public static minimum(): Date {
|
|
353
|
+
return new Date(EPOCH);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Returns the latest date supported by the NepaliDate class
|
|
358
|
+
* @returns JavaScript Date object representing the maximum supported date
|
|
359
|
+
*/
|
|
360
|
+
public static maximum(): Date {
|
|
361
|
+
return new Date(EPOCH + NEPALI_DATE_MAP[NEPALI_DATE_MAP.length - 1].daysTillNow * 86400000);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Returns the number of days in the current month
|
|
366
|
+
* @returns Number of days in the month
|
|
367
|
+
*/
|
|
368
|
+
public daysInMonth(): number {
|
|
369
|
+
const yearIndex = this.year - NEPALI_DATE_MAP[0].year;
|
|
370
|
+
return NEPALI_DATE_MAP[yearIndex].days[this.month];
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Checks if the current year is a leap year in the Nepali calendar
|
|
375
|
+
* @returns true if the year is a leap year, false otherwise
|
|
376
|
+
*/
|
|
377
|
+
public isLeapYear(): boolean {
|
|
378
|
+
const yearIndex = this.year - NEPALI_DATE_MAP[0].year;
|
|
379
|
+
return NEPALI_DATE_MAP[yearIndex].totalDays === 366;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Calculates the number of weeks in the current month
|
|
384
|
+
* @returns Number of weeks in the month
|
|
385
|
+
*/
|
|
386
|
+
public getWeeksInMonth(): number {
|
|
387
|
+
const firstDay = new NepaliDate(this.year, this.month, 1);
|
|
388
|
+
const firstDayOfWeek = firstDay.getDay();
|
|
389
|
+
const totalDays = this.daysInMonth();
|
|
390
|
+
return Math.ceil((firstDayOfWeek + totalDays) / 7);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Calculates the difference between two dates in the specified unit
|
|
395
|
+
* @param date NepaliDate to compare with
|
|
396
|
+
* @param unit Unit for the difference calculation ('year', 'month', or 'day')
|
|
397
|
+
* @returns Difference value in the specified unit
|
|
398
|
+
*/
|
|
399
|
+
public diff(date: NepaliDate, unit: 'year' | 'month' | 'day'): number {
|
|
400
|
+
switch (unit) {
|
|
401
|
+
case 'day':
|
|
402
|
+
return Math.floor((this.timestamp.getTime() - date.timestamp.getTime()) / 86400000);
|
|
403
|
+
|
|
404
|
+
case 'month':
|
|
405
|
+
const yearDiff = this.year - date.year;
|
|
406
|
+
const monthDiff = this.month - date.month;
|
|
407
|
+
return yearDiff * 12 + monthDiff;
|
|
408
|
+
|
|
409
|
+
case 'year':
|
|
410
|
+
return this.year - date.year;
|
|
411
|
+
|
|
412
|
+
default:
|
|
413
|
+
throw new Error('Invalid unit for diff calculation');
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Returns a new NepaliDate representing the start of the current day (00:00:00)
|
|
419
|
+
* @returns A new NepaliDate set to the start of the day
|
|
420
|
+
*/
|
|
421
|
+
public startOfDay(): NepaliDate {
|
|
422
|
+
const date = new Date(this.timestamp);
|
|
423
|
+
date.setHours(0, 0, 0, 0);
|
|
424
|
+
return new NepaliDate(date);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Returns a new NepaliDate representing the end of the current day (23:59:59.999)
|
|
429
|
+
* @returns A new NepaliDate set to the end of the day
|
|
430
|
+
*/
|
|
431
|
+
public endOfDay(): NepaliDate {
|
|
432
|
+
const date = new Date(this.timestamp);
|
|
433
|
+
date.setHours(23, 59, 59, 999);
|
|
434
|
+
return new NepaliDate(date);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Returns a new NepaliDate representing the start of the current month (1st day)
|
|
439
|
+
* @returns A new NepaliDate set to the first day of the month
|
|
440
|
+
*/
|
|
441
|
+
public startOfMonth(): NepaliDate {
|
|
442
|
+
return new NepaliDate(this.year, this.month, 1);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Returns a new NepaliDate representing the end of the current month (last day)
|
|
447
|
+
* @returns A new NepaliDate set to the last day of the month
|
|
448
|
+
*/
|
|
449
|
+
public endOfMonth(): NepaliDate {
|
|
450
|
+
const daysInMonth = this.daysInMonth();
|
|
451
|
+
return new NepaliDate(this.year, this.month, daysInMonth).endOfDay();
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Returns a new NepaliDate representing the start of the current year (1st Baisakh)
|
|
456
|
+
* @returns A new NepaliDate set to the first day of the year
|
|
457
|
+
*/
|
|
458
|
+
public startOfYear(): NepaliDate {
|
|
459
|
+
return new NepaliDate(this.year, 0, 1);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Returns a new NepaliDate representing the end of the current year (last day of Chaitra)
|
|
464
|
+
* @returns A new NepaliDate set to the last day of the year
|
|
465
|
+
*/
|
|
466
|
+
public endOfYear(): NepaliDate {
|
|
467
|
+
const yearIndex = this.year - NEPALI_DATE_MAP[0].year;
|
|
468
|
+
const daysInChaitra = NEPALI_DATE_MAP[yearIndex].days[11];
|
|
469
|
+
return new NepaliDate(this.year, 11, daysInChaitra).endOfDay();
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Returns the name of the specified Nepali month
|
|
474
|
+
* @param month Month index (0-11)
|
|
475
|
+
* @param short Whether to return the short form of the month name
|
|
476
|
+
* @returns Month name in Nepali or English
|
|
477
|
+
*/
|
|
478
|
+
public static getMonthName(month: number, short: boolean = false, nepali: boolean = false): string {
|
|
479
|
+
if (month < 0 || month > 11) {
|
|
480
|
+
throw new Error('Invalid month index, must be between 0-11');
|
|
481
|
+
}
|
|
482
|
+
let result = '';
|
|
483
|
+
if(nepali){
|
|
484
|
+
result = short ? MONTH_SHORT_NP[month] : MONTH_NP[month]
|
|
485
|
+
}else{
|
|
486
|
+
result = short ? MONTH_SHORT_EN[month] : MONTH_EN[month]
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return result;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Returns the name of the specified day of week
|
|
494
|
+
* @param day Day of week (0-6, where 0 is Sunday)
|
|
495
|
+
* @param short Whether to return the short form of the day name
|
|
496
|
+
* @returns Day name in Nepali or English
|
|
497
|
+
*/
|
|
498
|
+
public static getDayName(day: number, short: boolean = false, nepali: boolean = false): string {
|
|
499
|
+
if (day < 0 || day > 6) {
|
|
500
|
+
throw new Error('Invalid day index, must be between 0-6');
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
let result = '';
|
|
504
|
+
if(nepali){
|
|
505
|
+
result = short ? WEEK_SHORT_NP[day] : WEEK_NP[day]
|
|
506
|
+
}else{
|
|
507
|
+
result = short ? WEEK_SHORT_EN[day] : WEEK_EN[day]
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return result;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Checks if the specified Nepali date is valid
|
|
515
|
+
* @param year Nepali year to validate
|
|
516
|
+
* @param month Nepali month to validate (0-11)
|
|
517
|
+
* @param day Nepali day to validate
|
|
518
|
+
* @returns true if the date is valid, false otherwise
|
|
519
|
+
*/
|
|
520
|
+
public static isValid(year: number, month: number, day: number): boolean {
|
|
521
|
+
try {
|
|
522
|
+
if (year < NEPALI_DATE_MAP[0].year ||
|
|
523
|
+
year >= NEPALI_DATE_MAP[0].year + NEPALI_DATE_MAP.length) {
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
if (month < 0 || month > 11) {
|
|
528
|
+
return false;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const yearIndex = year - NEPALI_DATE_MAP[0].year;
|
|
532
|
+
const daysInMonth = NEPALI_DATE_MAP[yearIndex].days[month];
|
|
533
|
+
|
|
534
|
+
if (day < 1 || day > daysInMonth) {
|
|
535
|
+
return false;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return true;
|
|
539
|
+
} catch (error) {
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Checks if the current NepaliDate instance contains a valid date
|
|
546
|
+
* @returns true if the date is valid, false otherwise
|
|
547
|
+
*/
|
|
548
|
+
public isValid(): boolean {
|
|
549
|
+
return NepaliDate.isValid(this.year, this.month, this.day);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Generate calendar days for a given month, including trailing/leading days from adjacent months
|
|
554
|
+
* @param year Nepali year
|
|
555
|
+
* @param month Nepali month (0-11)
|
|
556
|
+
* @returns Array of day objects with date and isCurrentMonth flag
|
|
557
|
+
*/
|
|
558
|
+
public static getCalendarDays(year: number, month: number): { date: number, isCurrentMonth: boolean }[] {
|
|
559
|
+
if (!NepaliDate.isValid(year, month, 1)) {
|
|
560
|
+
throw new Error('Invalid year or month');
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const result: { date: number, isCurrentMonth: boolean }[] = [];
|
|
564
|
+
const yearIndex = year - NEPALI_DATE_MAP[0].year;
|
|
565
|
+
|
|
566
|
+
const firstDay = new NepaliDate(year, month, 1);
|
|
567
|
+
const firstDayOfWeek = firstDay.getDay();
|
|
568
|
+
|
|
569
|
+
const daysInMonth = NEPALI_DATE_MAP[yearIndex].days[month];
|
|
570
|
+
|
|
571
|
+
if (firstDayOfWeek > 0) {
|
|
572
|
+
let prevMonth = month - 1;
|
|
573
|
+
let prevYear = year;
|
|
574
|
+
if (prevMonth < 0) {
|
|
575
|
+
prevMonth = 11;
|
|
576
|
+
prevYear--;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if (prevYear >= NEPALI_DATE_MAP[0].year) {
|
|
580
|
+
const prevMonthIndex = prevYear - NEPALI_DATE_MAP[0].year;
|
|
581
|
+
const daysInPrevMonth = NEPALI_DATE_MAP[prevMonthIndex].days[prevMonth];
|
|
582
|
+
|
|
583
|
+
for (let i = 0; i < firstDayOfWeek; i++) {
|
|
584
|
+
result.push({
|
|
585
|
+
date: daysInPrevMonth - firstDayOfWeek + i + 1,
|
|
586
|
+
isCurrentMonth: false
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
593
|
+
result.push({
|
|
594
|
+
date: i,
|
|
595
|
+
isCurrentMonth: true
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const remainingDays = 42 - result.length;
|
|
600
|
+
|
|
601
|
+
if (remainingDays > 0) {
|
|
602
|
+
let nextMonth = month + 1;
|
|
603
|
+
let nextYear = year;
|
|
604
|
+
if (nextMonth > 11) {
|
|
605
|
+
nextMonth = 0;
|
|
606
|
+
nextYear++;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
if (nextYear < NEPALI_DATE_MAP[0].year + NEPALI_DATE_MAP.length) {
|
|
610
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
611
|
+
result.push({
|
|
612
|
+
date: i,
|
|
613
|
+
isCurrentMonth: false
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
return result;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Creates a copy of the current NepaliDate instance
|
|
624
|
+
* @returns A new NepaliDate instance with the same date and time
|
|
625
|
+
*/
|
|
626
|
+
public clone(): NepaliDate {
|
|
627
|
+
return new NepaliDate(this);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Checks if this date comes after the specified date
|
|
632
|
+
* @param date Date to compare with
|
|
633
|
+
* @returns true if this date is after the specified date, false otherwise
|
|
634
|
+
*/
|
|
635
|
+
public isAfter(date: NepaliDate): boolean {
|
|
636
|
+
return this.timestamp.getTime() > date.timestamp.getTime();
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Checks if this date comes before the specified date
|
|
641
|
+
* @param date Date to compare with
|
|
642
|
+
* @returns true if this date is before the specified date, false otherwise
|
|
643
|
+
*/
|
|
644
|
+
public isBefore(date: NepaliDate): boolean {
|
|
645
|
+
return this.timestamp.getTime() < date.timestamp.getTime();
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Checks if this date is equal to the specified date
|
|
650
|
+
* @param date Date to compare with
|
|
651
|
+
* @returns true if dates are exactly equal (year, month, day), false otherwise
|
|
652
|
+
*/
|
|
653
|
+
public isEqual(date: NepaliDate): boolean {
|
|
654
|
+
return this.year === date.year &&
|
|
655
|
+
this.month === date.month &&
|
|
656
|
+
this.day === date.day;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Checks if this date is the same as the specified date for the given unit
|
|
661
|
+
* @param date Date to compare with
|
|
662
|
+
* @param unit Unit to use for comparison ('year', 'month', or 'day')
|
|
663
|
+
* @returns true if dates are the same for the specified unit, false otherwise
|
|
664
|
+
*/
|
|
665
|
+
public isSame(date: NepaliDate, unit: 'year' | 'month' | 'day'): boolean {
|
|
666
|
+
switch (unit) {
|
|
667
|
+
case 'year':
|
|
668
|
+
return this.year === date.year;
|
|
669
|
+
|
|
670
|
+
case 'month':
|
|
671
|
+
return this.year === date.year && this.month === date.month;
|
|
672
|
+
|
|
673
|
+
case 'day':
|
|
674
|
+
return this.isEqual(date);
|
|
675
|
+
|
|
676
|
+
default:
|
|
677
|
+
throw new Error('Invalid unit for comparison');
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { NEPALI_DATE_MAP, NUMBER_NP } from "./Helper/Constants";
|
|
2
|
+
export { WEEK_EN, WEEK_NP, WEEK_SHORT_EN, WEEK_SHORT_NP } from "./Helper/Constants";
|
|
3
|
+
export { MONTH_EN, MONTH_NP, MONTH_SHORT_EN, MONTH_SHORT_NP } from "./Helper/Constants"
|
|
4
|
+
export { ADtoBS, BStoAD } from "./Helper/DateConverter";
|
|
5
|
+
export { NepaliDate } from "./NepaliDate";
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "ESNext",
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"moduleResolution": "Node",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"allowSyntheticDefaultImports": true,
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"declarationDir": "dist",
|
|
11
|
+
"outDir": "dist",
|
|
12
|
+
"baseUrl": ".",
|
|
13
|
+
"paths": {
|
|
14
|
+
"@/*": ["./src/*"]
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"include": [
|
|
18
|
+
"src/**/*.ts"
|
|
19
|
+
]
|
|
20
|
+
}
|