# nepal-utils-core

A highly performant, timezone-safe, and mathematically verified Nepali Date (Bikram Sambat) library for Node.js and the browser.

## Features

- 🌐 **Timezone Safe**: All calculations are locked to the `Asia/Kathmandu` (+05:45) timezone.
- ⚡ **Zero Dependencies**: Lightweight and fast, written in TypeScript.
- 📅 **Dual Calendar Conversion**: Precise conversions between Bikram Sambat (BS) and Gregorian (AD) calendars from **BS 2000 to BS 2089**.
- 🛠️ **Rich Utility APIs**:
  - **Date Formatting**: `formatBS` supports custom token formats, including Devanagari numerals and translated/transliterated months/weekdays.
  - **Age Calculator**: `calculateAgeBS` computes precise age in years, months, and days with correct day-borrowing relative to the BS calendar.
  - **Fiscal Year**: `getFiscalYear` correctly parses boundaries aligned with the Nepali fiscal cycle (starting Shrawan 1).
  - **Holidays & Calendar**: `getHolidays`, `isHoliday`, and `getHolidayEvent` expose full national holiday data.

---

## Installation

```bash
npm install nepal-utils-core
```

---

## Usage Examples

### 1. Date Conversion

Convert between Bikram Sambat (BS) and Gregorian (AD) calendars.

```typescript
import { bsToAd, adToBs } from 'nepal-utils-core';

// BS -> AD
// Acceptable inputs: string, object ({ year, month, day }), or separate arguments
const adDate1 = bsToAd(2080, 1, 17);
const adDate2 = bsToAd('2080-01-17');
const adDate3 = bsToAd({ year: 2080, month: 1, day: 17 });
console.log(adDate1.toISOString()); // Output: 2023-04-29T18:15:00.000Z (UTC equivalent)

// AD -> BS
// Acceptable inputs: Date object, timestamp, or ISO string
const bsDate1 = adToBs(new Date('2023-04-30T00:00:00+05:45'));
const bsDate2 = adToBs('2023-04-30');
console.log(bsDate1); // Output: { year: 2080, month: 1, day: 17 }
```

### 2. Formatting Date (`formatBS`)

```typescript
import { formatBS } from 'nepal-utils-core';

const date = { year: 2080, month: 1, day: 15 };

// Devanagari Formatting
console.log(formatBS(date, 'yyyy-mm-dd')); // Output: २०८०-०१-१५
console.log(formatBS(date, 'dddd, MMMM dd, yyyy')); // Output: शुक्रवार, वैशाख १५, २०८०

// English / Transliterated Formatting
console.log(formatBS(date, 'YYYY-MM-DD')); // Output: 2080-01-15
console.log(formatBS(date, 'ddde, MMME D, YYYY')); // Output: Friday, Baisakh 15, 2080
```

#### Supported Tokens

| Token | Description | Example Output |
|:---|:---|:---|
| `YYYY` | English 4-digit Year | `2080` |
| `yyyy` | Devanagari 4-digit Year | `२०८०` |
| `YY` | English 2-digit Year | `80` |
| `yy` | Devanagari 2-digit Year | `८०` |
| `MMMM` | Nepali Month Name | `वैशाख` |
| `MMME` | Transliterated Month Name | `Baisakh` |
| `MM` | English 2-digit Month | `01` |
| `mm` | Devanagari 2-digit Month | `०१` |
| `M` | English Month (1-12) | `1` |
| `m` | Devanagari Month (१-१२) | `१` |
| `DD` | English 2-digit Day | `15` |
| `dd` | Devanagari 2-digit Day | `१५` |
| `D` | English Day (1-32) | `15` |
| `d` | Devanagari Day (१-३२) | `१५` |
| `dddd` | Nepali Weekday Name | `शुक्रवार` |
| `ddd` | Nepali Weekday Short | `शुक` |
| `ddde` | English Weekday Name | `Friday` |

### 3. Age Calculation (`calculateAgeBS`)

Calculates the difference between Date of Birth and a reference date (defaults to current date).

```typescript
import { calculateAgeBS } from 'nepal-utils-core';

const dob = '2070-01-15';
const referenceDate = '2080-01-10';

const age = calculateAgeBS(dob, referenceDate);
console.log(age); 
// Output: { years: 9, months: 11, days: 26 } (handles day-borrowing correctly based on calendar)
```

### 4. Fiscal Year (`getFiscalYear`)

Fetches the current fiscal year (aligned with Nepali Shrawan 1 boundary).

```typescript
import { getFiscalYear } from 'nepal-utils-core';

console.log(getFiscalYear('2080-03-31')); 
// Output: { startYear: 2079, endYear: 2080, formatted: "2079/2080" }

console.log(getFiscalYear('2080-04-01')); 
// Output: { startYear: 2080, endYear: 2081, formatted: "2080/2081" } (starts Shrawan 1)
```

### 5. Holidays & Calendar Utilities

Check and fetch calendar events and holiday listings.

```typescript
import { getHolidays, isHoliday, getHolidayEvent } from 'nepal-utils-core';

// Get all holidays in BS year 2080
const holidays = getHolidays(2080);
console.log(holidays[0]); 
// Output: { date: "2080-01-01", name: "नयाँ वर्ष / मेष संक्रान्ति / बिस्का: जात्रा" }

// Check if a date is a public holiday
console.log(isHoliday('2080-01-01')); // Output: true
console.log(isHoliday('2080-01-02')); // Output: false

// Get holiday details
const holidayDetails = getHolidayEvent('2080-01-01');
console.log(holidayDetails); 
// Output: { date: "2080-01-01", name: "नयाँ वर्ष / मेष संक्रान्ति / बिस्का: जात्रा" }
```

---

## Technical Information

- **Calendar Bounds**: BS 2000-01-01 to BS 2089-12-30.
- **Anchor Offset**: BS 2000-01-01 maps directly to AD 1943-04-14.
- **Timezone Safety**: Local GMT offsite differences are handled internally by converting dates to UTC timestamps adjusted by +5:45 (+345 minutes) to ensure uniform day boundaries regardless of client machine timezone settings.

## License

Apache License 2.0. Feel free to use and distribute.
