nepali-date-library 1.1.5 → 1.1.7

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 CHANGED
@@ -1,362 +1,1162 @@
1
1
  # NepaliDate Library
2
2
 
3
- ## Overview
4
- The `NepaliDate` library provides a proper way to work with Nepali (Bikram Sambat) dates in TypeScript/JavaScript. It allows you to create, manipulate, format, and convert between Nepali and Gregorian dates with support for fiscal years, quarters, and extensive date operations.
3
+ A comprehensive TypeScript/JavaScript library for working with Nepali (Bikram Sambat) dates. This library provides full support for creating, manipulating, formatting, and converting between Nepali and Gregorian dates, with additional features for fiscal years, quarters, and extensive date operations.
4
+
5
+ ## Features
6
+
7
+ - 🗓️ **Complete Nepali Calendar Support** - Accurate Bikram Sambat calendar from 1976 BS to 2100 BS
8
+ - 🔄 **Flexible Date Conversion** - Convert between AD and BS dates with custom format support
9
+ - 📅 **Date Manipulation** - Add/subtract days, months, and years with proper overflow handling
10
+ - 🌐 **Localization Support** - Full English and Nepali language support for months and days
11
+ - 📊 **Fiscal Year Support** - Built-in fiscal year and quarter calculations
12
+ - 🎯 **Date Range Operations** - Start/end of day, week, month, year calculations
13
+ - ⚡ **TypeScript Ready** - Full type safety and IntelliSense support
14
+ - 🧮 **Calendar Generation** - Generate calendar grids for UI components
15
+ - 🎨 **Custom Format Support** - Parse and format dates in multiple patterns
5
16
 
6
17
  ## Installation
7
- ```sh
18
+
19
+ ```bash
8
20
  npm install nepali-date-library
9
21
  ```
10
22
 
11
- ## Importing the Library
12
- ```ts
23
+ ## Quick Start
24
+
25
+ ```typescript
13
26
  import { NepaliDate, ADtoBS, BStoAD } from 'nepali-date-library';
14
- ```
15
27
 
16
- ## Class: `NepaliDate`
28
+ // Create today's date in Nepali calendar
29
+ const today = new NepaliDate();
30
+ console.log(today.toString()); // 2081/10/15
17
31
 
18
- ### Constructors
19
- ```ts
20
- new NepaliDate();
21
- new NepaliDate(date: Date | NepaliDate | number | string);
22
- new NepaliDate(year: number, month: number, day: number);
32
+ // Convert between calendars with default formats
33
+ const bsDate = ADtoBS('2025-02-22'); // "2081-10-10"
34
+ const adDate = BStoAD('2081-10-14'); // "2025-02-26"
35
+
36
+ // Convert with custom formats
37
+ const customBS = ADtoBS('22/02/2025', 'DD/MM/YYYY', 'YYYY.MM.DD'); // "2081.10.10"
38
+ const customAD = BStoAD('10.10.2081', 'DD.MM.YYYY', 'MM-DD-YYYY'); // "10-10-2025"
39
+
40
+ // Format dates
41
+ const formatted = today.format('MMMM DD, YYYY'); // "Magh 15, 2081"
42
+ const nepali = today.format('mmmm dd, yyyy'); // "माघ १५, २०८१"
23
43
  ```
24
- - Creates a `NepaliDate` instance.
25
- - Accepts either no arguments (current date), a JavaScript `Date`, another `NepaliDate`, a timestamp, or a formatted date string.
26
- - Can also accept year, month (0-11), and day (1-32) as separate arguments.
27
44
 
28
- ### Date Conversion Functions
45
+ ## API Reference
29
46
 
30
- #### Pre-built Conversion Functions
31
- ```ts
32
- import { ADtoBS, BStoAD } from 'nepali-date-library';
47
+ ### Importing
33
48
 
34
- // Convert AD to BS
35
- const bsDate = ADtoBS('2025-02-22'); // Returns: '2081-10-10'
49
+ ```typescript
50
+ // Main classes and functions
51
+ import { NepaliDate, ADtoBS, BStoAD } from 'nepali-date-library';
36
52
 
37
- // Convert BS to AD
38
- const adDate = BStoAD('2081-10-14'); // Returns: '2025-02-26'
53
+ // Constants
54
+ import {
55
+ NEPALI_DATE_MAP,
56
+ NUMBER_NP,
57
+ WEEK_EN, WEEK_NP, WEEK_SHORT_EN, WEEK_SHORT_NP,
58
+ MONTH_EN, MONTH_NP, MONTH_SHORT_EN, MONTH_SHORT_NP
59
+ } from 'nepali-date-library';
39
60
  ```
40
61
 
41
- #### Class Method
42
- ```ts
43
- const nepaliDate = new NepaliDate();
44
- const adDate = nepaliDate.getEnglishDate(); // Returns JavaScript Date object
62
+ ### Date Conversion Utilities
63
+
64
+ #### `ADtoBS(adDate: string, inputFormat?: string, outputFormat?: string): string`
65
+
66
+ Converts an Anno Domini (AD) date to a Bikram Sambat (BS) date with custom format support.
67
+
68
+ **Parameters:**
69
+ - `adDate` - The AD date string
70
+ - `inputFormat` - The input date format pattern (default: "YYYY-MM-DD")
71
+ - `outputFormat` - The output date format pattern (default: "YYYY-MM-DD")
72
+
73
+ **Returns:** The corresponding BS date in the specified output format
74
+
75
+ **Supported Input/Output Formats:**
76
+ - `YYYY-MM-DD`, `YYYY/MM/DD`, `YYYY.MM.DD`
77
+ - `DD-MM-YYYY`, `DD/MM/YYYY`, `DD.MM.YYYY`
78
+ - `MM-DD-YYYY`, `MM/DD/YYYY`, `MM.DD.YYYY`
79
+ - `DD MM YYYY`, `YYYY MM DD`
80
+
81
+ ```typescript
82
+ // Default format conversion
83
+ const bsDate = ADtoBS('2025-02-22'); // "2081-10-10"
84
+
85
+ // Custom input format
86
+ const bsDate2 = ADtoBS('22/02/2025', 'DD/MM/YYYY'); // "2081-10-10"
87
+
88
+ // Custom input and output formats
89
+ const bsDate3 = ADtoBS('22.02.2025', 'DD.MM.YYYY', 'YYYY/MM/DD'); // "2081/10/10"
90
+
91
+ // US format to Nepali format
92
+ const bsDate4 = ADtoBS('02-22-2025', 'MM-DD-YYYY', 'DD.MM.YYYY'); // "10.10.2081"
45
93
  ```
46
94
 
47
- ---
95
+ #### `BStoAD(bsDate: string, inputFormat?: string, outputFormat?: string): string`
96
+
97
+ Converts a Bikram Sambat (BS) date to an Anno Domini (AD) date with custom format support.
98
+
99
+ **Parameters:**
100
+ - `bsDate` - The BS date string (supports both English and Nepali numerals)
101
+ - `inputFormat` - The input date format pattern (default: "YYYY-MM-DD")
102
+ - `outputFormat` - The output date format pattern (default: "YYYY-MM-DD")
103
+
104
+ **Returns:** The corresponding AD date in the specified output format
105
+
106
+ ```typescript
107
+ // Default format conversion
108
+ const adDate = BStoAD('2081-10-14'); // "2025-02-26"
48
109
 
49
- ### Getters
50
- ```ts
51
- getYear(): number; // Returns Nepali year
52
- getMonth(): number; // Returns Nepali month (0-11)
53
- getDate(): number; // Returns Nepali day (1-32)
54
- getDay(): number; // Returns day of week (0-6, 0 = Sunday)
55
- getHours(): number; // Returns hour (0-23)
56
- getMinutes(): number; // Returns minutes (0-59)
57
- getSeconds(): number; // Returns seconds (0-59)
58
- getMilliseconds(): number; // Returns milliseconds (0-999)
59
- getTime(): number; // Returns timestamp in milliseconds
110
+ // Custom input format
111
+ const adDate2 = BStoAD('14/10/2081', 'DD/MM/YYYY'); // "2025-02-26"
112
+
113
+ // Custom input and output formats
114
+ const adDate3 = BStoAD('14.10.2081', 'DD.MM.YYYY', 'MM/DD/YYYY'); // "02/26/2025"
115
+
116
+ // Nepali numerals support
117
+ const adDate4 = BStoAD('२०८१-१०-१४'); // "2025-02-26"
118
+
119
+ // Mixed format conversion
120
+ const adDate5 = BStoAD('10 14 2081', 'MM DD YYYY', 'DD-MM-YYYY'); // "26-02-2025"
60
121
  ```
61
122
 
62
- ---
123
+ ### NepaliDate Class
124
+
125
+ #### Constructors
126
+
127
+ ```typescript
128
+ // Current date
129
+ const today = new NepaliDate();
130
+
131
+ // From JavaScript Date
132
+ const fromDate = new NepaliDate(new Date());
63
133
 
64
- ### Setters
65
- ```ts
66
- setYear(year: number): void;
67
- setMonth(month: number): void;
68
- setDate(day: number): void;
69
- set(year: number, month: number, day: number): void;
134
+ // From string
135
+ const fromString = new NepaliDate('2081-10-15');
136
+
137
+ // From components (year, month 0-11, day 1-32)
138
+ const fromComponents = new NepaliDate(2081, 9, 15);
139
+
140
+ // From timestamp
141
+ const fromTimestamp = new NepaliDate(1645123200000);
142
+
143
+ // From another NepaliDate
144
+ const copy = new NepaliDate(existingNepaliDate);
70
145
  ```
71
- - Updates the Nepali date components and synchronizes the internal timestamp.
72
146
 
73
- ---
147
+ #### Properties
74
148
 
75
- ### Parsing
76
- ```ts
77
- parse(dateString: string): void;
149
+ ```typescript
150
+ public timestamp: Date; // Equivalent JavaScript Date
151
+ public year: number; // Nepali year (BS)
152
+ public month: number; // Nepali month (0-11)
153
+ public day: number; // Nepali day (1-32)
78
154
  ```
79
- - Parses a date string and updates the current instance
80
- - Supports formats: YYYY-MM-DD, YYYY/MM/DD, or YYYY.MM.DD
81
155
 
82
- ---
156
+ #### Basic Getters
157
+
158
+ ```typescript
159
+ const date = new NepaliDate();
160
+
161
+ date.getYear(); // Returns Nepali year
162
+ date.getMonth(); // Returns Nepali month (0-11)
163
+ date.getDate(); // Returns Nepali day (1-32)
164
+ date.getDay(); // Returns day of week (0-6, 0=Sunday)
165
+ date.getHours(); // Returns hour (0-23)
166
+ date.getMinutes(); // Returns minutes (0-59)
167
+ date.getSeconds(); // Returns seconds (0-59)
168
+ date.getMilliseconds(); // Returns milliseconds (0-999)
169
+ date.getTime(); // Returns timestamp
170
+ date.getEnglishDate(); // Returns equivalent JavaScript Date
171
+ ```
172
+
173
+ #### Setters
174
+
175
+ ```typescript
176
+ const date = new NepaliDate();
83
177
 
84
- ### Formatting
85
- ```ts
86
- format(formatStr: string): string;
87
- toString(): string; // Returns format: YYYY/MM/DD (1-indexed month)
178
+ date.setYear(2082); // Set Nepali year
179
+ date.setMonth(5); // Set Nepali month (0-11)
180
+ date.setDate(15); // Set Nepali day (1-32)
181
+ date.set(2081, 9, 15); // Set all components at once
88
182
  ```
89
183
 
90
- #### Available Format Tokens:
91
- - **English Formats:**
92
- - `YYYY` - Full Year (e.g., 2080)
93
- - `MM` - Month with leading zero (01-12)
94
- - `M` - Month without leading zero (1-12)
95
- - `MMM` - Short month name (Bai, Cha)
96
- - `MMMM` - Long month name (Baisakh, Chaitra)
97
- - `DD` - Day with leading zero (01-32)
98
- - `D` - Day without leading zero (1-32)
99
- - `DDD` - Short day name (Sun, Sat)
100
- - `DDDD` - Full day name (Sunday)
184
+ #### Formatting
101
185
 
102
- - **Nepali Formats:**
103
- - `yyyy` - Full Year (e.g., २०८१)
104
- - `mm` - Month with leading zero (०१-१२)
105
- - `m` - Month without leading zero (१-१२)
106
- - `mmm` - Short month name (बै, चै)
107
- - `mmmm` - Long month name (बैशाख, चैत्र)
108
- - `dd` - Day with leading zero (०१-३२)
109
- - `d` - Day without leading zero (१-३२)
110
- - `ddd` - Short day name (आइत, शनि)
111
- - `dddd` - Full day name (आइतबार)
186
+ The `format()` method supports extensive formatting options:
112
187
 
113
- ---
188
+ ```typescript
189
+ const date = new NepaliDate(2081, 9, 15);
190
+
191
+ // English formats
192
+ date.format('YYYY-MM-DD'); // "2081-10-15"
193
+ date.format('MMMM DD, YYYY'); // "Magh 15, 2081"
194
+ date.format('MMM D, YYYY'); // "Mag 15, 2081"
195
+ date.format('DDDD, MMMM DD'); // "Monday, Magh 15"
196
+
197
+ // Nepali formats
198
+ date.format('yyyy-mm-dd'); // "२०८१-१०-१५"
199
+ date.format('mmmm dd, yyyy'); // "माघ १५, २०८१"
200
+ date.format('dddd, mmmm dd'); // "सोमबार, माघ १५"
201
+ ```
202
+
203
+ **Format Tokens:**
204
+
205
+ | Token | Description | Example |
206
+ |-------|-------------|---------|
207
+ | `YYYY` | 4-digit year | 2081 |
208
+ | `MM` | Month with leading zero | 01-12 |
209
+ | `M` | Month without leading zero | 1-12 |
210
+ | `MMMM` | Full month name | Baisakh |
211
+ | `MMM` | Short month name | Bai |
212
+ | `DD` | Day with leading zero | 01-32 |
213
+ | `D` | Day without leading zero | 1-32 |
214
+ | `DDDD` | Full day name | Sunday |
215
+ | `DDD` | Short day name | Sun |
216
+ | `yyyy` | 4-digit year (Nepali) | २०८१ |
217
+ | `mm` | Month with leading zero (Nepali) | ०१-१२ |
218
+ | `m` | Month without leading zero (Nepali) | १-१२ |
219
+ | `mmmm` | Full month name (Nepali) | बैशाख |
220
+ | `mmm` | Short month name (Nepali) | बै |
221
+ | `dd` | Day with leading zero (Nepali) | ०१-३२ |
222
+ | `d` | Day without leading zero (Nepali) | १-३२ |
223
+ | `dddd` | Full day name (Nepali) | आइतबार |
224
+ | `ddd` | Short day name (Nepali) | आइत |
225
+
226
+ #### Date Manipulation
227
+
228
+ All manipulation methods return new instances (immutable):
229
+
230
+ ```typescript
231
+ const date = new NepaliDate(2081, 9, 15);
114
232
 
115
- ### Date Manipulation
116
- ```ts
117
- addDays(days: number): NepaliDate;
118
- addMonths(months: number): NepaliDate;
119
- addYears(years: number): NepaliDate;
233
+ const futureDate = date.addDays(10); // 10 days later
234
+ const pastDate = date.addMonths(-2); // 2 months earlier
235
+ const nextYear = date.addYears(1); // 1 year later
236
+
237
+ // Original date remains unchanged
238
+ console.log(date.toString()); // "2081/10/15"
239
+ console.log(futureDate.toString()); // "2081/10/25"
120
240
  ```
121
- - Adds a specified number of days, months, or years to the date and returns a new `NepaliDate` instance.
122
241
 
123
- ---
242
+ #### Date Comparison
124
243
 
125
- ### Date Information Methods
244
+ ```typescript
245
+ const date1 = new NepaliDate(2081, 5, 10);
246
+ const date2 = new NepaliDate(2081, 5, 15);
126
247
 
127
- #### `daysInMonth(): number`
128
- Returns the number of days in the current month.
248
+ date1.isAfter(date2); // false
249
+ date1.isBefore(date2); // true
250
+ date1.isEqual(date2); // false
251
+ date1.isSame(date2, 'month'); // true
252
+ date1.isSame(date2, 'year'); // true
129
253
 
130
- #### `isLeapYear(): boolean`
131
- Checks if the current year is a leap year in the Nepali calendar.
254
+ // Calculate differences
255
+ date1.diff(date2, 'day'); // -5
256
+ date1.diff(date2, 'month'); // 0
257
+ date1.diff(date2, 'year'); // 0
258
+ ```
132
259
 
133
- #### `getWeeksInMonth(): number`
134
- Calculates the number of weeks in the current month.
260
+ #### Date Range Operations
135
261
 
136
- ---
262
+ ```typescript
263
+ const date = new NepaliDate(2081, 5, 15);
137
264
 
138
- ### Date Comparison Methods
265
+ // Day boundaries
266
+ const startOfDay = date.startOfDay(); // 00:00:00
267
+ const endOfDay = date.endOfDay(); // 23:59:59.999
139
268
 
140
- #### `diff(date: NepaliDate, unit: 'year' | 'month' | 'day'): number`
141
- Calculates the difference between two `NepaliDate` instances.
269
+ // Week boundaries (default: Sunday start)
270
+ const startOfWeek = date.startOfWeek(); // Previous/current Sunday
271
+ const endOfWeek = date.endOfWeek(); // Following/current Saturday
142
272
 
143
- #### `isAfter(date: NepaliDate): boolean`
144
- Checks if this date comes after the specified date.
273
+ // Week boundaries (Monday start)
274
+ const startOfWeekMon = date.startOfWeek(1); // Previous/current Monday
275
+ const endOfWeekMon = date.endOfWeek(1); // Following/current Sunday
145
276
 
146
- #### `isBefore(date: NepaliDate): boolean`
147
- Checks if this date comes before the specified date.
277
+ // Month boundaries
278
+ const startOfMonth = date.startOfMonth(); // 1st day of month
279
+ const endOfMonth = date.endOfMonth(); // Last day of month
148
280
 
149
- #### `isEqual(date: NepaliDate): boolean`
150
- Checks if this date is exactly equal to the specified date (year, month, day).
281
+ // Year boundaries
282
+ const startOfYear = date.startOfYear(); // 1st Baisakh
283
+ const endOfYear = date.endOfYear(); // Last day of Chaitra
284
+ ```
151
285
 
152
- #### `isSame(date: NepaliDate, unit: 'year' | 'month' | 'day'): boolean`
153
- Checks if this date is the same as the specified date for the given unit.
286
+ #### Calendar Year Quarters
154
287
 
155
- ---
288
+ ```typescript
289
+ // Get current quarter (1-4)
290
+ const currentQuarter = new NepaliDate().getCurrentQuarter();
156
291
 
157
- ### Date Range Methods
292
+ // Get specific quarter dates
293
+ const q1 = NepaliDate.getQuarter(1, 2081);
294
+ console.log(q1.start.toString()); // "2081/1/1" (1st Baisakh)
295
+ console.log(q1.end.toString()); // "2081/3/32" (Last day of Asar)
158
296
 
159
- #### `startOfDay(): NepaliDate`
160
- Returns a new `NepaliDate` representing the start of the current day (00:00:00).
297
+ // Get all quarters for a year
298
+ const quarters = NepaliDate.getQuarters(2081);
299
+ console.log(quarters.Q1); // {start: NepaliDate, end: NepaliDate}
300
+ console.log(quarters.Q2); // {start: NepaliDate, end: NepaliDate}
301
+ console.log(quarters.Q3); // {start: NepaliDate, end: NepaliDate}
302
+ console.log(quarters.Q4); // {start: NepaliDate, end: NepaliDate}
303
+ ```
161
304
 
162
- #### `endOfDay(): NepaliDate`
163
- Returns a new `NepaliDate` representing the end of the current day (23:59:59.999).
305
+ **Quarter Mapping (Calendar Year):**
306
+ - **Q1:** Baisakh, Jestha, Asar (months 0-2)
307
+ - **Q2:** Shrawan, Bhadra, Aswin (months 3-5)
308
+ - **Q3:** Kartik, Mangsir, Poush (months 6-8)
309
+ - **Q4:** Magh, Falgun, Chaitra (months 9-11)
164
310
 
165
- #### `startOfWeek(startOfWeek: number = 0): NepaliDate`
166
- Returns a new `NepaliDate` representing the start of the week containing this date.
167
- - `startOfWeek`: Day to consider as start of week (0-6, where 0 = Sunday, 1 = Monday, etc.)
311
+ #### Fiscal Year Operations
168
312
 
169
- #### `endOfWeek(startOfWeek: number = 0): NepaliDate`
170
- Returns a new `NepaliDate` representing the end of the week containing this date.
313
+ The Nepali fiscal year starts from **Shrawan 1st** (month 3, day 1).
171
314
 
172
- #### `startOfMonth(): NepaliDate`
173
- Returns a new `NepaliDate` representing the first day of the current month.
315
+ ```typescript
316
+ // Get current fiscal year
317
+ const currentFY = NepaliDate.getCurrentFiscalYear();
174
318
 
175
- #### `endOfMonth(): NepaliDate`
176
- Returns a new `NepaliDate` representing the last day of the current month.
319
+ // Get current fiscal year quarter (1-4)
320
+ const date = new NepaliDate();
321
+ const fyQuarter = date.getCurrentFiscalYearQuarter();
177
322
 
178
- #### `startOfYear(): NepaliDate`
179
- Returns a new `NepaliDate` representing the first day of the current Nepali year (1st Baisakh).
323
+ // Get current fiscal year quarter dates
324
+ const quarterDates = date.getCurrentFiscalYearQuarterDates();
325
+ console.log(quarterDates.start.toString());
326
+ console.log(quarterDates.end.toString());
180
327
 
181
- #### `endOfYear(): NepaliDate`
182
- Returns a new `NepaliDate` representing the last day of the current Nepali year (last day of Chaitra).
328
+ // Get specific fiscal year quarter
329
+ const fyQ1 = NepaliDate.getFiscalYearQuarter(1, 2081);
330
+ console.log(fyQ1.start.toString()); // "2081/4/1" (1st Shrawan)
331
+ console.log(fyQ1.end.toString()); // "2081/6/30" (Last day of Aswin)
183
332
 
184
- ---
333
+ // Get all fiscal year quarters
334
+ const fyQuarters = NepaliDate.getFiscalYearQuarters(2081);
335
+ ```
185
336
 
186
- ### Quarter and Fiscal Year Methods
337
+ **Fiscal Year Quarter Mapping:**
338
+ - **Q1:** Shrawan, Bhadra, Aswin (months 3-5)
339
+ - **Q2:** Kartik, Mangsir, Poush (months 6-8)
340
+ - **Q3:** Magh, Falgun, Chaitra (months 9-11)
341
+ - **Q4:** Baisakh, Jestha, Asar (months 0-2) *[spans to next calendar year]*
187
342
 
188
- #### `getCurrentQuarter(): number`
189
- Returns the quarter number (1-4) for the current date.
343
+ #### Date Information
190
344
 
191
- #### `getCurrentFiscalYearQuarter(): number`
192
- Returns the current fiscal year quarter number (1-4) for the current date.
193
- - Fiscal year starts from Shrawan 1st (month 3, day 1)
345
+ ```typescript
346
+ const date = new NepaliDate(2081, 4, 15); // Bhadra 15, 2081
194
347
 
195
- #### `getCurrentFiscalYearQuarterDates(): { start: NepaliDate; end: NepaliDate }`
196
- Returns the start and end dates of the current fiscal year quarter.
348
+ date.daysInMonth(); // 31 (days in Bhadra 2081)
349
+ date.isLeapYear(); // true/false
350
+ date.getWeeksInMonth(); // Number of weeks in current month
351
+ date.isValid(); // true/false
197
352
 
198
- ---
353
+ // Static validation
354
+ NepaliDate.isValid(2081, 4, 32); // false (invalid day)
355
+ NepaliDate.isValid(2081, 4, 31); // true
356
+ ```
199
357
 
200
- ### Static Methods
358
+ #### Calendar Generation
201
359
 
202
- #### Date Range Utilities
203
- ```ts
204
- static minimum(): Date; // Returns earliest supported date
205
- static maximum(): Date; // Returns latest supported date
360
+ Generate calendar data for building UI components:
361
+
362
+ ```typescript
363
+ const calendarData = NepaliDate.getCalendarDays(2081, 4); // Bhadra 2081
364
+
365
+ console.log(calendarData);
366
+ // {
367
+ // prevRemainingDays: 2, // Days from previous month
368
+ // prevMonth: {
369
+ // year: 2081,
370
+ // month: 3,
371
+ // days: [30, 31] // Last days of previous month
372
+ // },
373
+ // currentMonth: {
374
+ // year: 2081,
375
+ // month: 4,
376
+ // days: [1, 2, 3, ..., 31] // All days of current month
377
+ // },
378
+ // nextMonth: {
379
+ // year: 2081,
380
+ // month: 5,
381
+ // days: [1, 2, 3, 4, 5] // First days of next month
382
+ // },
383
+ // remainingDays: 5 // Days from next month
384
+ // }
206
385
  ```
207
386
 
208
- #### Validation
209
- ```ts
210
- static isValid(year: number, month: number, day: number): boolean;
211
- isValid(): boolean; // Instance method
387
+ #### Utility Methods
388
+
389
+ ```typescript
390
+ // Get name utilities
391
+ NepaliDate.getMonthName(0, false, false); // "Baisakh"
392
+ NepaliDate.getMonthName(0, true, false); // "Bai"
393
+ NepaliDate.getMonthName(0, false, true); // "बैशाख"
394
+ NepaliDate.getMonthName(0, true, true); // "बै"
395
+
396
+ NepaliDate.getDayName(0, false, false); // "Sunday"
397
+ NepaliDate.getDayName(0, true, false); // "Sun"
398
+ NepaliDate.getDayName(0, false, true); // "आइतबार"
399
+ NepaliDate.getDayName(0, true, true); // "आइत"
400
+
401
+ // Date boundaries
402
+ NepaliDate.minimum(); // Earliest supported date
403
+ NepaliDate.maximum(); // Latest supported date
404
+
405
+ // Clone instance
406
+ const copy = date.clone(); // Deep copy of NepaliDate
212
407
  ```
213
408
 
214
- #### Name Utilities
215
- ```ts
216
- static getMonthName(month: number, short: boolean = false, nepali: boolean = false): string;
217
- static getDayName(day: number, short: boolean = false, nepali: boolean = false): string;
409
+ ## Advanced Format Examples
410
+
411
+ ### Multi-Format Date Conversion
412
+
413
+ ```typescript
414
+ import { ADtoBS, BStoAD } from 'nepali-date-library';
415
+
416
+ // Converting from various AD formats to BS
417
+ const europeanToBS = ADtoBS('22/02/2025', 'DD/MM/YYYY'); // "2081-10-10"
418
+ const americanToBS = ADtoBS('02-22-2025', 'MM-DD-YYYY'); // "2081-10-10"
419
+ const dotFormatToBS = ADtoBS('2025.02.22', 'YYYY.MM.DD'); // "2081-10-10"
420
+ const spaceFormatToBS = ADtoBS('22 02 2025', 'DD MM YYYY'); // "2081-10-10"
421
+
422
+ // Converting with custom output formats
423
+ const customOutput1 = ADtoBS('2025-02-22', 'YYYY-MM-DD', 'DD/MM/YYYY'); // "10/10/2081"
424
+ const customOutput2 = ADtoBS('22/02/2025', 'DD/MM/YYYY', 'YYYY.MM.DD'); // "2081.10.10"
425
+
426
+ // Converting from various BS formats to AD
427
+ const bsSlashToAD = BStoAD('10/10/2081', 'DD/MM/YYYY'); // "2025-02-22"
428
+ const bsDotToAD = BStoAD('2081.10.10', 'YYYY.MM.DD'); // "2025-02-22"
429
+ const bsSpaceToAD = BStoAD('10 10 2081', 'DD MM YYYY'); // "2025-02-22"
430
+
431
+ // Converting with custom AD output formats
432
+ const adCustom1 = BStoAD('2081-10-10', 'YYYY-MM-DD', 'MM/DD/YYYY'); // "02/22/2025"
433
+ const adCustom2 = BStoAD('10/10/2081', 'DD/MM/YYYY', 'DD.MM.YYYY'); // "22.02.2025"
218
434
  ```
219
435
 
220
- #### Calendar Generation
221
- ```ts
222
- static getCalendarDays(year: number, month: number): {
223
- prevRemainingDays: number,
224
- prevMonth: { year: number, month: number, days: number[] },
225
- currentMonth: { year: number, month: number, days: number[] },
226
- nextMonth: { year: number, month: number, days: number[] },
227
- remainingDays: number
436
+ ### Handling Different Date Sources
437
+
438
+ ```typescript
439
+ // API data conversion utility
440
+ function convertAPIDate(dateStr: string, sourceFormat: string, targetCalendar: 'AD' | 'BS', targetFormat: string = 'YYYY-MM-DD') {
441
+ try {
442
+ if (targetCalendar === 'BS') {
443
+ return ADtoBS(dateStr, sourceFormat, targetFormat);
444
+ } else {
445
+ return BStoAD(dateStr, sourceFormat, targetFormat);
446
+ }
447
+ } catch (error) {
448
+ throw new Error(`Date conversion failed: ${error.message}`);
449
+ }
228
450
  }
451
+
452
+ // Usage examples
453
+ const dbDate = convertAPIDate('2025/02/22', 'YYYY/MM/DD', 'BS', 'DD-MM-YYYY'); // "10-10-2081"
454
+ const userInput = convertAPIDate('22.10.2081', 'DD.MM.YYYY', 'AD', 'MM/DD/YYYY'); // "02/26/2025"
455
+ const csvDate = convertAPIDate('02 22 2025', 'MM DD YYYY', 'BS', 'YYYY/MM/DD'); // "2081/10/10"
229
456
  ```
230
- Generates calendar days for a given month, including trailing/leading days from adjacent months.
231
457
 
232
- #### Quarter Methods
233
- ```ts
234
- static getQuarter(quarter: number, year?: number): { start: NepaliDate; end: NepaliDate };
235
- static getQuarters(year?: number): {
236
- Q1: { start: NepaliDate; end: NepaliDate };
237
- Q2: { start: NepaliDate; end: NepaliDate };
238
- Q3: { start: NepaliDate; end: NepaliDate };
239
- Q4: { start: NepaliDate; end: NepaliDate };
240
- };
458
+ ### Nepali Numeral Support
459
+
460
+ The library automatically handles Nepali numerals in input:
461
+
462
+ ```typescript
463
+ // Both of these work identically
464
+ const withEnglishNumerals = BStoAD('2081-10-14');
465
+ const withNepaliNumerals = BStoAD('२०८१-१०-१४');
466
+
467
+ // Mixed numerals are also supported
468
+ const mixedNumerals = BStoAD('२०८१-10-१४');
469
+
470
+ // All produce the same result: "2025-02-26"
241
471
  ```
242
472
 
243
- #### Fiscal Year Methods
244
- ```ts
245
- static getCurrentFiscalYear(): number;
246
- static getFiscalYearQuarter(quarter: number, fiscalYear?: number): { start: NepaliDate; end: NepaliDate };
247
- static getFiscalYearQuarters(fiscalYear?: number): {
248
- Q1: { start: NepaliDate; end: NepaliDate };
249
- Q2: { start: NepaliDate; end: NepaliDate };
250
- Q3: { start: NepaliDate; end: NepaliDate };
251
- Q4: { start: NepaliDate; end: NepaliDate };
252
- };
473
+ ### Constants
474
+
475
+ #### Calendar Data
476
+
477
+ ```typescript
478
+ // Complete calendar mapping (1976-2100 BS)
479
+ NEPALI_DATE_MAP: Array<{
480
+ year: number;
481
+ days: number[]; // Days in each month [31, 32, 31, ...]
482
+ totalDays: number; // Total days in year
483
+ daysTillNow: number; // Cumulative days from epoch
484
+ }>
253
485
  ```
254
486
 
255
- #### Utility Methods
256
- ```ts
257
- clone(): NepaliDate; // Creates a copy of the current instance
487
+ #### Week Names
488
+
489
+ ```typescript
490
+ // English
491
+ WEEK_EN: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
492
+ WEEK_SHORT_EN: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
493
+
494
+ // Nepali
495
+ WEEK_NP: ['आइतबार', 'सोमबार', 'मंगलबार', 'बुधबार', 'बिहिबार', 'शुक्रबार', 'शनिबार']
496
+ WEEK_SHORT_NP: ['आइत', 'सोम', 'मंगल', 'बुध', 'बिहि', 'शुक्र', 'शनि']
258
497
  ```
259
498
 
260
- ---
499
+ #### Month Names
261
500
 
262
- ## Example Usage
501
+ ```typescript
502
+ // English
503
+ MONTH_EN: ["Baisakh", "Jestha", "Asar", "Shrawan", "Bhadra", "Aswin", "Kartik", "Mangsir", "Poush", "Magh", "Falgun", "Chaitra"]
504
+ MONTH_SHORT_EN: ["Bai", "Jes", "Asa", "Shr", "Bhd", "Asw", "Kar", "Man", "Pou", "Mag", "Fal", "Cha"]
263
505
 
264
- ### Basic Usage
265
- ```ts
266
- const today = new NepaliDate();
267
- console.log(today.toString()); // 2081/10/15
506
+ // Nepali
507
+ MONTH_NP: ['बैशाख', 'जेठ', 'असार', 'श्रावण', 'भाद्र', 'आश्विन', 'कार्तिक', 'मंसिर', 'पौष', 'माघ', 'फाल्गुण', 'चैत्र']
508
+ MONTH_SHORT_NP: ['बै', 'जे', 'अ', 'श्रा', 'भा', 'आ', 'का', 'मं', 'पौ', 'मा', 'फा', 'चै']
509
+ ```
510
+
511
+ #### Numbers
268
512
 
269
- const formatted = today.format('YYYY-MM-DD');
270
- console.log(formatted); // 2081-10-15
513
+ ```typescript
514
+ // Nepali numerals (0-9)
515
+ NUMBER_NP: ['०', '१', '२', '३', '४', '५', '६', '७', '८', '९']
271
516
 
272
- const nepaliFormatted = today.format('yyyy-mm-dd');
273
- console.log(nepaliFormatted); // २०८१-१०-१५
517
+ // Usage example
518
+ function toNepaliNumber(num: string): string {
519
+ return num.split('').map(digit => NUMBER_NP[parseInt(digit)] || digit).join('');
520
+ }
521
+
522
+ console.log(toNepaliNumber('2081')); // "२०८१"
274
523
  ```
275
524
 
276
- ### Date Manipulation
277
- ```ts
278
- const date = new NepaliDate(2081, 9, 15);
279
- const futureDate = date.addDays(10);
280
- const pastDate = date.addMonths(-2);
525
+ ## Examples
526
+
527
+ ### Basic Date Operations
528
+
529
+ ```typescript
530
+ import { NepaliDate } from 'nepali-date-library';
531
+
532
+ const date = new NepaliDate(2081, 9, 15); // Magh 15, 2081
533
+
534
+ // Formatting
535
+ console.log(date.toString()); // "2081/10/15"
536
+ console.log(date.format('YYYY-MM-DD')); // "2081-10-15"
537
+ console.log(date.format('MMMM DD, YYYY')); // "Magh 15, 2081"
538
+ console.log(date.format('dddd, mmmm dd, yyyy')); // "सोमबार, माघ १५, २०८१"
539
+
540
+ // Date arithmetic
541
+ const nextWeek = date.addDays(7);
542
+ const nextMonth = date.addMonths(1);
281
543
  const nextYear = date.addYears(1);
544
+
545
+ console.log(nextWeek.format('YYYY-MM-DD')); // "2081-10-22"
546
+ console.log(nextMonth.format('YYYY-MM-DD')); // "2081-11-15"
547
+ console.log(nextYear.format('YYYY-MM-DD')); // "2082-10-15"
282
548
  ```
283
549
 
284
- ### Date Comparison
285
- ```ts
286
- const date1 = new NepaliDate(2081, 5, 10);
287
- const date2 = new NepaliDate(2081, 5, 15);
550
+ ### Working with Different Date Formats
288
551
 
289
- console.log(date1.isBefore(date2)); // true
290
- console.log(date1.diff(date2, 'day')); // -5
291
- console.log(date1.isSame(date2, 'month')); // true
292
- ```
552
+ ```typescript
553
+ import { ADtoBS, BStoAD } from 'nepali-date-library';
293
554
 
294
- ### Working with Quarters
295
- ```ts
296
- // Get current quarter
297
- const currentQuarter = new NepaliDate().getCurrentQuarter();
555
+ // Database integration - handle various formats
556
+ function handleDatabaseDate(dateStr: string, sourceFormat: string): string {
557
+ // Convert to standard BS format for storage
558
+ return ADtoBS(dateStr, sourceFormat, 'YYYY-MM-DD');
559
+ }
298
560
 
299
- // Get fiscal year quarter
300
- const fiscalQuarter = new NepaliDate().getCurrentFiscalYearQuarter();
561
+ // User interface - display in user's preferred format
562
+ function displayUserDate(bsDate: string, userPreference: string): string {
563
+ return BStoAD(bsDate, 'YYYY-MM-DD', userPreference);
564
+ }
301
565
 
302
- // Get all quarters for a year
303
- const quarters = NepaliDate.getQuarters(2081);
304
- console.log(quarters.Q1); // { start: NepaliDate, end: NepaliDate }
566
+ // Examples
567
+ const dbDate1 = handleDatabaseDate('22/02/2025', 'DD/MM/YYYY'); // "2081-10-10"
568
+ const dbDate2 = handleDatabaseDate('02.22.2025', 'MM.DD.YYYY'); // "2081-10-10"
305
569
 
306
- // Get fiscal year quarters
307
- const fiscalQuarters = NepaliDate.getFiscalYearQuarters(2081);
570
+ const userDate1 = displayUserDate('2081-10-10', 'DD/MM/YYYY'); // "22/02/2025"
571
+ const userDate2 = displayUserDate('2081-10-10', 'MM-DD-YYYY'); // "02-22-2025"
308
572
  ```
309
573
 
310
- ### Calendar Generation
311
- ```ts
312
- const calendarData = NepaliDate.getCalendarDays(2081, 4);
313
- console.log(calendarData.currentMonth.days); // [1, 2, 3, ..., 30]
314
- console.log(calendarData.prevMonth.days); // Days from previous month
574
+ ### Working with Localized Names
575
+
576
+ ```typescript
577
+ import { MONTH_EN, MONTH_NP, WEEK_EN, WEEK_NP, NUMBER_NP } from 'nepali-date-library';
578
+
579
+ const date = new NepaliDate();
580
+
581
+ // Get localized month and day names
582
+ const monthNameEn = MONTH_EN[date.getMonth()];
583
+ const monthNameNp = MONTH_NP[date.getMonth()];
584
+ const dayNameEn = WEEK_EN[date.getDay()];
585
+ const dayNameNp = WEEK_NP[date.getDay()];
586
+
587
+ // Convert to Nepali numerals
588
+ const nepaliYear = date.getYear().toString()
589
+ .split('')
590
+ .map(digit => NUMBER_NP[parseInt(digit)])
591
+ .join('');
592
+
593
+ console.log(`${dayNameEn}, ${monthNameEn} ${date.getDate()}, ${date.getYear()}`);
594
+ // "Monday, Magh 15, 2081"
595
+
596
+ console.log(`${dayNameNp}, ${monthNameNp} ${NUMBER_NP[1]}${NUMBER_NP[5]}, ${nepaliYear}`);
597
+ // "सोमबार, माघ १५, २०८१"
315
598
  ```
316
599
 
317
- ### Date Range Operations
318
- ```ts
319
- const date = new NepaliDate(2081, 5, 15);
600
+ ### Fiscal Year Operations
601
+
602
+ ```typescript
603
+ import { NepaliDate } from 'nepali-date-library';
320
604
 
321
- const startOfWeek = date.startOfWeek(); // Sunday of current week
322
- const endOfWeek = date.endOfWeek(); // Saturday of current week
323
- const startOfMonth = date.startOfMonth(); // 1st day of current month
324
- const endOfYear = date.endOfYear(); // Last day of current year
605
+ // Current fiscal year info
606
+ const currentFY = NepaliDate.getCurrentFiscalYear();
607
+ console.log(`Current Fiscal Year: ${currentFY}`);
608
+
609
+ const date = new NepaliDate();
610
+ const currentFYQuarter = date.getCurrentFiscalYearQuarter();
611
+ console.log(`Current FY Quarter: Q${currentFYQuarter}`);
612
+
613
+ // Get all fiscal year quarters
614
+ const fyQuarters = NepaliDate.getFiscalYearQuarters(2081);
615
+
616
+ Object.entries(fyQuarters).forEach(([quarter, dates]) => {
617
+ console.log(`${quarter}: ${dates.start.format('YYYY-MM-DD')} to ${dates.end.format('YYYY-MM-DD')}`);
618
+ });
619
+
620
+ // Output:
621
+ // Q1: 2081-04-01 to 2081-06-30 (Shrawan to Aswin)
622
+ // Q2: 2081-07-01 to 2081-09-30 (Kartik to Poush)
623
+ // Q3: 2081-10-01 to 2081-12-30 (Magh to Chaitra)
624
+ // Q4: 2082-01-01 to 2082-03-32 (Baisakh to Asar)
325
625
  ```
326
626
 
327
- ### Validation
328
- ```ts
329
- // Static validation
330
- console.log(NepaliDate.isValid(2081, 4, 32)); // false (day out of range)
627
+ ### Building a Calendar Component
628
+
629
+ ```typescript
630
+ import { NepaliDate, WEEK_EN, MONTH_EN } from 'nepali-date-library';
631
+
632
+ function generateCalendar(year: number, month: number) {
633
+ const calendarData = NepaliDate.getCalendarDays(year, month);
634
+
635
+ // Create 6-week calendar grid
636
+ const calendar = [];
637
+ let dayIndex = 0;
638
+
639
+ for (let week = 0; week < 6; week++) {
640
+ const weekDays = [];
641
+
642
+ for (let day = 0; day < 7; day++) {
643
+ if (week === 0 && day < calendarData.prevRemainingDays) {
644
+ // Previous month days
645
+ weekDays.push({
646
+ day: calendarData.prevMonth.days[day],
647
+ isCurrentMonth: false,
648
+ isPrevMonth: true,
649
+ date: new NepaliDate(
650
+ calendarData.prevMonth.year,
651
+ calendarData.prevMonth.month,
652
+ calendarData.prevMonth.days[day]
653
+ )
654
+ });
655
+ } else if (dayIndex < calendarData.currentMonth.days.length) {
656
+ // Current month days
657
+ weekDays.push({
658
+ day: calendarData.currentMonth.days[dayIndex],
659
+ isCurrentMonth: true,
660
+ isPrevMonth: false,
661
+ date: new NepaliDate(year, month, calendarData.currentMonth.days[dayIndex])
662
+ });
663
+ dayIndex++;
664
+ } else {
665
+ // Next month days
666
+ const nextDayIndex = dayIndex - calendarData.currentMonth.days.length;
667
+ weekDays.push({
668
+ day: calendarData.nextMonth.days[nextDayIndex],
669
+ isCurrentMonth: false,
670
+ isPrevMonth: false,
671
+ date: new NepaliDate(
672
+ calendarData.nextMonth.year,
673
+ calendarData.nextMonth.month,
674
+ calendarData.nextMonth.days[nextDayIndex]
675
+ )
676
+ });
677
+ }
678
+ }
679
+ calendar.push(weekDays);
680
+ }
681
+
682
+ return {
683
+ month: MONTH_EN[month],
684
+ year: year,
685
+ weeks: calendar,
686
+ weekHeaders: WEEK_EN
687
+ };
688
+ }
331
689
 
332
- // Instance validation
333
- const date = new NepaliDate(2081, 5, 10);
334
- console.log(date.isValid()); // true
690
+ // Usage
691
+ const calendar = generateCalendar(2081, 9); // Magh 2081
692
+ console.log(calendar.month); // "Magh"
693
+ console.log(calendar.weeks); // 6 weeks of calendar data
335
694
  ```
336
695
 
337
- ### Name Utilities
338
- ```ts
339
- // Month names
340
- console.log(NepaliDate.getMonthName(0, false, false)); // "Baisakh"
341
- console.log(NepaliDate.getMonthName(0, true, true)); // "बै"
696
+ ### Date Conversion Workflow
342
697
 
343
- // Day names
344
- console.log(NepaliDate.getDayName(0, false, true)); // "आइतबार"
345
- console.log(NepaliDate.getDayName(1, true, false)); // "Mon"
698
+ ```typescript
699
+ import { NepaliDate, ADtoBS, BStoAD } from 'nepali-date-library';
700
+
701
+ // Convert user input
702
+ function handleDateConversion(inputDate: string, fromCalendar: 'AD' | 'BS') {
703
+ try {
704
+ if (fromCalendar === 'AD') {
705
+ const bsDate = ADtoBS(inputDate);
706
+ const nepaliDate = new NepaliDate(bsDate);
707
+
708
+ return {
709
+ converted: bsDate,
710
+ formatted: nepaliDate.format('MMMM DD, YYYY'),
711
+ nepaliFormatted: nepaliDate.format('mmmm dd, yyyy'),
712
+ dayName: nepaliDate.format('DDDD')
713
+ };
714
+ } else {
715
+ const adDate = BStoAD(inputDate);
716
+ const jsDate = new Date(adDate);
717
+
718
+ return {
719
+ converted: adDate,
720
+ formatted: jsDate.toLocaleDateString('en-US', {
721
+ year: 'numeric',
722
+ month: 'long',
723
+ day: 'numeric'
724
+ })
725
+ };
726
+ }
727
+ } catch (error) {
728
+ throw new Error(`Invalid date: ${error.message}`);
729
+ }
730
+ }
731
+
732
+ // Examples
733
+ console.log(handleDateConversion('2025-02-22', 'AD'));
734
+ // { converted: "2081-10-10", formatted: "Magh 10, 2081", ... }
735
+
736
+ console.log(handleDateConversion('2081-10-14', 'BS'));
737
+ // { converted: "2025-02-26", formatted: "February 26, 2025" }
346
738
  ```
347
739
 
348
- ---
740
+ ### Advanced Date Range Queries
741
+
742
+ ```typescript
743
+ import { NepaliDate } from 'nepali-date-library';
744
+
745
+ // Find all Fridays in a month
746
+ function getFridaysInMonth(year: number, month: number): NepaliDate[] {
747
+ const fridays: NepaliDate[] = [];
748
+ const startOfMonth = new NepaliDate(year, month, 1);
749
+ const endOfMonth = startOfMonth.endOfMonth();
750
+
751
+ let current = startOfMonth.clone();
752
+
753
+ // Find first Friday
754
+ while (current.getDay() !== 5) { // 5 = Friday
755
+ current = current.addDays(1);
756
+ }
757
+
758
+ // Collect all Fridays
759
+ while (current.isBefore(endOfMonth) || current.isEqual(endOfMonth)) {
760
+ fridays.push(current.clone());
761
+ current = current.addDays(7);
762
+ }
763
+
764
+ return fridays;
765
+ }
766
+
767
+ // Usage
768
+ const fridaysInMagh = getFridaysInMonth(2081, 9);
769
+ fridaysInMagh.forEach(friday => {
770
+ console.log(friday.format('DDDD, MMMM DD')); // "Friday, Magh 3", etc.
771
+ });
772
+ ```
349
773
 
350
774
  ## Error Handling
351
- - Throws an error if an invalid date format is used in constructor or parse method
352
- - Throws an error if the Nepali date is out of the supported range
353
- - Validates input parameters and throws appropriate errors for invalid values
775
+
776
+ The library provides comprehensive error handling:
777
+
778
+ ```typescript
779
+ try {
780
+ // Invalid date format
781
+ const invalid1 = ADtoBS('25-02-22'); // Throws: Invalid date format
782
+
783
+ // Out of range
784
+ const invalid2 = new NepaliDate(1975, 0, 1); // Throws: Year out of range
785
+
786
+ // Invalid day for month
787
+ const invalid3 = new NepaliDate(2081, 4, 32); // Throws: Invalid date
788
+
789
+ // Invalid quarter
790
+ const invalid4 = NepaliDate.getQuarter(5, 2081); // Throws: Quarter must be 1-4
791
+
792
+ } catch (error) {
793
+ console.error(error.message);
794
+ }
795
+
796
+ // Safe validation
797
+ if (NepaliDate.isValid(2081, 9, 15)) {
798
+ const safeDate = new NepaliDate(2081, 9, 15);
799
+ console.log('Date created successfully');
800
+ }
801
+ ```
354
802
 
355
803
  ## Supported Date Range
356
- The library supports Nepali dates within a specific range. Use `NepaliDate.minimum()` and `NepaliDate.maximum()` to get the supported date boundaries.
357
804
 
358
- ## Acknowledgements
359
- This project was inspired by [nepali-date](https://github.com/sharingapples/nepali-date).
805
+ - **Start:** 1976 BS (Bikram Sambat year 1976)
806
+ - **End:** 2100 BS (Bikram Sambat year 2100)
807
+ - **Total:** 125 years of accurate calendar data
808
+
809
+ ```typescript
810
+ const minDate = NepaliDate.minimum(); // JavaScript Date for 1976/1/1 BS
811
+ const maxDate = NepaliDate.maximum(); // JavaScript Date for 2100/12/31 BS
812
+ ```
813
+
814
+ ## Important Notes
815
+
816
+ ### Month Indexing
817
+ - **Internal storage and input:** Months are 0-indexed (0-11) like JavaScript Date
818
+ - **Display:** `toString()` method shows months as 1-12 for readability
819
+ - **Baisakh = 0, Jestha = 1, ..., Chaitra = 11**
820
+
821
+ ### Immutability
822
+ All date manipulation methods return new instances rather than modifying existing ones:
823
+
824
+ ```typescript
825
+ const original = new NepaliDate(2081, 9, 15);
826
+ const modified = original.addDays(10);
827
+
828
+ console.log(original.toString()); // "2081/10/15" (unchanged)
829
+ console.log(modified.toString()); // "2081/10/25" (new instance)
830
+ ```
831
+
832
+ ### Thread Safety
833
+ The library is designed for functional programming patterns and is safe for concurrent use.
834
+
835
+ ## Migration from Other Libraries
836
+
837
+ If you're migrating from other Nepali date libraries:
838
+
839
+ ```typescript
840
+ // Instead of: nepaliDate.getBS()
841
+ const nepaliDate = new NepaliDate();
842
+ console.log(nepaliDate.toString());
843
+
844
+ // Instead of: nepaliDate.getAD()
845
+ console.log(nepaliDate.getEnglishDate());
846
+
847
+ // Instead of: nepaliDate.format('YYYY-MM-DD')
848
+ console.log(nepaliDate.format('YYYY-MM-DD'));
849
+ ```
850
+
851
+ ## TypeScript Support
852
+
853
+ The library is written in TypeScript and provides full type definitions:
854
+
855
+ ```typescript
856
+ import { NepaliDate } from 'nepali-date-library';
857
+
858
+ // Full IntelliSense support
859
+ const date: NepaliDate = new NepaliDate();
860
+ const quarter: number = date.getCurrentQuarter(); // Type-safe
861
+ const formatted: string = date.format('YYYY-MM-DD'); // Type-safe
862
+ ```
863
+
864
+ ## Browser Compatibility
865
+
866
+ - **Modern Browsers:** Chrome 60+, Firefox 55+, Safari 10.1+, Edge 79+
867
+ - **Node.js:** Version 12+
868
+ - **Dependencies:** None (zero external dependencies)
869
+
870
+ ## Contributing
871
+
872
+ We welcome contributions! Please feel free to submit issues and enhancement requests.
360
873
 
361
874
  ## License
362
- MIT License
875
+
876
+ MIT License - see LICENSE file for details.
877
+
878
+ ## Acknowledgments
879
+
880
+ This project was inspired by [nepali-date](https://github.com/sharingapples/nepali-date) and provides enhanced functionality with TypeScript support and additional features.
881
+
882
+ ## Performance Considerations
883
+
884
+ ### Memory Usage
885
+ - Minimal memory footprint with efficient date calculations
886
+ - Calendar data is pre-computed and stored in constants
887
+ - No unnecessary object creation in core operations
888
+
889
+ ### Computation Speed
890
+ - Fast date conversions using pre-calculated lookup tables
891
+ - O(1) complexity for most operations
892
+ - Optimized algorithms for date arithmetic
893
+
894
+ ## Common Use Cases
895
+
896
+ ### E-commerce Applications
897
+ ```typescript
898
+ // Calculate delivery dates in Nepali calendar
899
+ function calculateDeliveryDate(orderDate: string, deliveryDays: number) {
900
+ const bsOrderDate = new NepaliDate(ADtoBS(orderDate));
901
+ const deliveryDate = bsOrderDate.addDays(deliveryDays);
902
+
903
+ return {
904
+ nepali: deliveryDate.format('MMMM DD, YYYY'),
905
+ english: deliveryDate.format('mmmm dd, yyyy'),
906
+ dayOfWeek: deliveryDate.format('DDDD')
907
+ };
908
+ }
909
+
910
+ const delivery = calculateDeliveryDate('2025-02-20', 5);
911
+ console.log(delivery);
912
+ // { nepali: "Magh 13, 2081", english: "माघ १३, २०८१", dayOfWeek: "Wednesday" }
913
+ ```
914
+
915
+ ### Financial Applications
916
+ ```typescript
917
+ // Calculate fiscal year quarters for reporting
918
+ function getFiscalYearReport(fiscalYear: number) {
919
+ const quarters = NepaliDate.getFiscalYearQuarters(fiscalYear);
920
+
921
+ return Object.entries(quarters).map(([quarter, dates]) => ({
922
+ quarter,
923
+ startDate: dates.start.format('YYYY-MM-DD'),
924
+ endDate: dates.end.format('YYYY-MM-DD'),
925
+ daysInQuarter: dates.start.diff(dates.end, 'day') * -1 + 1
926
+ }));
927
+ }
928
+
929
+ const report = getFiscalYearReport(2081);
930
+ console.log(report);
931
+ ```
932
+
933
+ ### Event Planning
934
+ ```typescript
935
+ // Find next occurrence of a specific weekday
936
+ function findNextWeekday(startDate: NepaliDate, targetDay: number): NepaliDate {
937
+ let current = startDate.addDays(1);
938
+
939
+ while (current.getDay() !== targetDay) {
940
+ current = current.addDays(1);
941
+ }
942
+
943
+ return current;
944
+ }
945
+
946
+ // Find all Saturdays in a month for scheduling
947
+ function getSaturdaysInMonth(year: number, month: number): NepaliDate[] {
948
+ const saturdays: NepaliDate[] = [];
949
+ const monthStart = new NepaliDate(year, month, 1);
950
+ const monthEnd = monthStart.endOfMonth();
951
+
952
+ let current = monthStart.clone();
953
+
954
+ // Find first Saturday
955
+ while (current.getDay() !== 6) {
956
+ current = current.addDays(1);
957
+ }
958
+
959
+ // Collect all Saturdays
960
+ while (current.getDate() <= monthEnd.getDate() && current.getMonth() === month) {
961
+ saturdays.push(current.clone());
962
+ current = current.addDays(7);
963
+ }
964
+
965
+ return saturdays;
966
+ }
967
+ ```
968
+
969
+ ### Age Calculation
970
+ ```typescript
971
+ // Calculate age in Nepali calendar
972
+ function calculateNepaliAge(birthDate: string): {
973
+ years: number;
974
+ months: number;
975
+ days: number;
976
+ totalDays: number;
977
+ } {
978
+ const birth = new NepaliDate(birthDate);
979
+ const today = new NepaliDate();
980
+
981
+ let years = today.getYear() - birth.getYear();
982
+ let months = today.getMonth() - birth.getMonth();
983
+ let days = today.getDate() - birth.getDate();
984
+
985
+ // Adjust for negative days
986
+ if (days < 0) {
987
+ months--;
988
+ const prevMonth = today.addMonths(-1);
989
+ days += prevMonth.daysInMonth();
990
+ }
991
+
992
+ // Adjust for negative months
993
+ if (months < 0) {
994
+ years--;
995
+ months += 12;
996
+ }
997
+
998
+ const totalDays = birth.diff(today, 'day') * -1;
999
+
1000
+ return { years, months, days, totalDays };
1001
+ }
1002
+
1003
+ const age = calculateNepaliAge('2060-05-15');
1004
+ console.log(`Age: ${age.years} years, ${age.months} months, ${age.days} days`);
1005
+ ```
1006
+
1007
+ ## Integration Examples
1008
+
1009
+ ### React Component
1010
+ ```typescript
1011
+ import React, { useState } from 'react';
1012
+ import { NepaliDate, MONTH_EN } from 'nepali-date-library';
1013
+
1014
+ const NepaliDatePicker: React.FC = () => {
1015
+ const [selectedDate, setSelectedDate] = useState(new NepaliDate());
1016
+
1017
+ const handleDateChange = (year: number, month: number, day: number) => {
1018
+ if (NepaliDate.isValid(year, month, day)) {
1019
+ setSelectedDate(new NepaliDate(year, month, day));
1020
+ }
1021
+ };
1022
+
1023
+ return (
1024
+ <div>
1025
+ <h3>Selected Date: {selectedDate.format('MMMM DD, YYYY')}</h3>
1026
+ <p>In Nepali: {selectedDate.format('mmmm dd, yyyy')}</p>
1027
+ <p>Day: {selectedDate.format('DDDD')}</p>
1028
+ <p>Gregorian: {selectedDate.getEnglishDate().toLocaleDateString()}</p>
1029
+
1030
+ {/* Add your date picker UI here */}
1031
+ </div>
1032
+ );
1033
+ };
1034
+ ```
1035
+
1036
+ ### Express.js API Endpoint
1037
+ ```typescript
1038
+ import express from 'express';
1039
+ import { NepaliDate, ADtoBS, BStoAD } from 'nepali-date-library';
1040
+
1041
+ const app = express();
1042
+
1043
+ app.get('/api/convert/:fromCalendar/:date', (req, res) => {
1044
+ try {
1045
+ const { fromCalendar, date } = req.params;
1046
+
1047
+ if (fromCalendar === 'ad') {
1048
+ const bsDate = ADtoBS(date);
1049
+ const nepaliDate = new NepaliDate(bsDate);
1050
+
1051
+ res.json({
1052
+ original: date,
1053
+ converted: bsDate,
1054
+ formatted: {
1055
+ english: nepaliDate.format('MMMM DD, YYYY'),
1056
+ nepali: nepaliDate.format('mmmm dd, yyyy')
1057
+ },
1058
+ dayOfWeek: nepaliDate.format('DDDD'),
1059
+ quarter: nepaliDate.getCurrentQuarter(),
1060
+ fiscalYear: NepaliDate.getCurrentFiscalYear(),
1061
+ isLeapYear: nepaliDate.isLeapYear()
1062
+ });
1063
+ } else if (fromCalendar === 'bs') {
1064
+ const adDate = BStoAD(date);
1065
+ const jsDate = new Date(adDate);
1066
+
1067
+ res.json({
1068
+ original: date,
1069
+ converted: adDate,
1070
+ formatted: jsDate.toLocaleDateString('en-US', {
1071
+ year: 'numeric',
1072
+ month: 'long',
1073
+ day: 'numeric'
1074
+ })
1075
+ });
1076
+ } else {
1077
+ res.status(400).json({ error: 'Invalid calendar type. Use "ad" or "bs"' });
1078
+ }
1079
+ } catch (error) {
1080
+ res.status(400).json({ error: error.message });
1081
+ }
1082
+ });
1083
+
1084
+ // Fiscal year endpoints
1085
+ app.get('/api/fiscal-year/:year/quarters', (req, res) => {
1086
+ try {
1087
+ const year = parseInt(req.params.year);
1088
+ const quarters = NepaliDate.getFiscalYearQuarters(year);
1089
+
1090
+ const response = Object.entries(quarters).map(([quarter, dates]) => ({
1091
+ quarter,
1092
+ startDate: dates.start.format('YYYY-MM-DD'),
1093
+ endDate: dates.end.format('YYYY-MM-DD'),
1094
+ startFormatted: dates.start.format('MMMM DD, YYYY'),
1095
+ endFormatted: dates.end.format('MMMM DD, YYYY')
1096
+ }));
1097
+
1098
+ res.json(response);
1099
+ } catch (error) {
1100
+ res.status(400).json({ error: error.message });
1101
+ }
1102
+ });
1103
+ ```
1104
+
1105
+ ## Testing
1106
+
1107
+ ### Unit Test Examples
1108
+ ```typescript
1109
+ import { NepaliDate, ADtoBS, BStoAD } from 'nepali-date-library';
1110
+
1111
+ describe('NepaliDate Library', () => {
1112
+ test('should convert AD to BS correctly', () => {
1113
+ expect(ADtoBS('2025-02-22')).toBe('2081-10-10');
1114
+ expect(ADtoBS('2024-12-15')).toBe('2081-08-30');
1115
+ });
1116
+
1117
+ test('should convert BS to AD correctly', () => {
1118
+ expect(BStoAD('2081-10-14')).toBe('2025-02-26');
1119
+ expect(BStoAD('2081-05-15')).toBe('2024-08-30');
1120
+ });
1121
+
1122
+ test('should handle date arithmetic correctly', () => {
1123
+ const date = new NepaliDate(2081, 9, 15);
1124
+ const futureDate = date.addDays(10);
1125
+
1126
+ expect(futureDate.getDate()).toBe(25);
1127
+ expect(futureDate.getMonth()).toBe(9);
1128
+ expect(futureDate.getYear()).toBe(2081);
1129
+ });
1130
+
1131
+ test('should validate dates correctly', () => {
1132
+ expect(NepaliDate.isValid(2081, 4, 31)).toBe(true);
1133
+ expect(NepaliDate.isValid(2081, 4, 32)).toBe(false);
1134
+ expect(NepaliDate.isValid(2081, 12, 1)).toBe(false); // Month out of range
1135
+ });
1136
+
1137
+ test('should handle fiscal year calculations', () => {
1138
+ const currentFY = NepaliDate.getCurrentFiscalYear();
1139
+ const quarters = NepaliDate.getFiscalYearQuarters(currentFY);
1140
+
1141
+ expect(Object.keys(quarters)).toEqual(['Q1', 'Q2', 'Q3', 'Q4']);
1142
+ expect(quarters.Q1.start.getMonth()).toBe(3); // Shrawan (index 3)
1143
+ });
1144
+ });
1145
+ ```
1146
+
1147
+ ## Frequently Asked Questions
1148
+
1149
+ ### Why are months 0-indexed?
1150
+ To maintain consistency with JavaScript's Date object and provide seamless integration with existing JavaScript/TypeScript codebases.
1151
+
1152
+ ### How accurate are the date conversions?
1153
+ The library uses official Nepali calendar data from 1976 BS to 2100 BS and constantly updates the maps every year, ensuring high accuracy for all supported date ranges.
1154
+
1155
+ ### Can I use this library for historical dates before 1976 BS?
1156
+ No, the library only supports dates from 1976 BS onwards due to available calendar data limitations.
1157
+
1158
+ ### How do I handle timezone differences?
1159
+ The library works with the local timezone of the JavaScript environment. For UTC operations, convert the underlying JavaScript Date to UTC before processing.
1160
+
1161
+ ### Is the library suitable for server-side applications?
1162
+ Yes, the library is designed to work seamlessly in both browser and Node.js environments.