@subrotosaha/bangla-date
Version:
A simple utility package for string manipulation in JavaScript.
1,117 lines • 52.9 kB
TypeScript
type Language = "en" | "bn" | "hi";
/**
* Base error class for all BanglaDate failures.
*
* Extend this class (or catch it) to handle any error thrown by the library.
* All more-specific error types (`BanglaDateRangeError`, `BanglaDateParseError`)
* inherit from this class, so a single `catch (e)` block can test
* `e instanceof BanglaDateError` to distinguish library errors from unrelated ones.
*
* @example
* try {
* BanglaDate.parse('invalid');
* } catch (e) {
* if (e instanceof BanglaDateError) console.error('Library error:', e.message);
* }
*/
export declare class BanglaDateError extends Error {
/**
* @param message - Human-readable description of what went wrong.
*/
constructor(message: string);
}
/**
* Thrown when a numeric argument (year, month, or day) falls outside its
* valid range.
*
* Common triggers:
* - Month not in 1–12 in `fromBanglaDate()` or `parse()`.
* - Day exceeding the maximum for the given month (e.g. day 32, or day 31 in
* a 30-day month such as Ashwin).
*
* @example
* try {
* BanglaDate.fromBanglaDate(1432, 13, 1); // month 13 doesn't exist
* } catch (e) {
* if (e instanceof BanglaDateRangeError) console.error(e.message);
* // "Month must be between 1 and 12, got 13."
* }
*/
export declare class BanglaDateRangeError extends BanglaDateError {
/**
* @param message - Human-readable description of what value was out of range.
*/
constructor(message: string);
}
/**
* Thrown when a date string passed to `BanglaDate.parse()` cannot be
* interpreted as a valid Bangla date.
*
* Common triggers:
* - The string does not follow the required `"DD MonthName YYYY"` format.
* - The month name is not one of the 12 recognised English Bangla month names.
* - The day or year tokens are not valid integers.
*
* @example
* try {
* BanglaDate.parse('2025-04-14'); // wrong format
* } catch (e) {
* if (e instanceof BanglaDateParseError) console.error(e.message);
* // 'Expected "DD MonthName YYYY" (e.g. "15 Boishakh 1432").'
* }
*/
export declare class BanglaDateParseError extends BanglaDateError {
/**
* @param message - Human-readable description of why parsing failed.
*/
constructor(message: string);
}
declare class BanglaDate {
private banglaYear;
private banglaMonthIndex;
private banglaDay;
private gregorianDate;
private language;
/**
* Creates a `BanglaDate` instance from a Gregorian `Date` object.
*
* The constructor converts the supplied Gregorian date to the corresponding
* Bangla calendar date following the **revised Bangladesh National Calendar**
* (established by the 1966 Reform Committee).
*
* - Pohela Boishakh (1 Boishakh) is fixed to **April 14 UTC** every year.
* - All date arithmetic is performed in **UTC** to avoid host-timezone drift.
* - Months 1–5 (Boishakh–Bhadra) contain 31 days; months 6–10 (Ashwin–Magh)
* contain 30 days; month 11 (Falgun) has 29 days in a common year and 30
* days in a Bangla leap year (when the following Gregorian year is a leap year);
* month 12 (Chaitra) always contains 30 days.
*
* @param gregorianDate - Any valid JavaScript `Date` object. Time-of-day
* components are preserved so that arithmetic and formatting methods can
* access the full timestamp.
* @param language - Output language for all text-returning methods.
* - `"en"` (default) — English (Latin digits, English month/weekday names)
* - `"bn"` — Bengali (Bengali digits ০–৯, Bengali names)
* - `"hi"` — Hindi (Devanagari digits ०–९, Hindi names)
*
* @example
* // English (default)
* const d = new BanglaDate(new Date('2025-04-14'), 'en');
* d.toString(); // "1 Boishakh 1432 BA"
*
* @example
* // Bengali output
* const d = new BanglaDate(new Date('2025-04-14'), 'bn');
* d.toString(); // "১ বৈশাখ ১৪৩২ বঙ্গাব্দ"
*/
constructor(gregorianDate: Date, language?: Language);
/**
* Creates a `BanglaDate` for the **current moment**, preserving the
* full time-of-day component of the underlying timestamp.
*
* This is the live equivalent of `new BanglaDate(new Date())`. Use it
* when you need hour/minute/second precision (e.g. in a clock, log
* timestamp, or countdown). If you only need the date portion (no time),
* prefer `today()` which normalises to midnight UTC.
*
* @param language - Output language for all text-returning methods.
* - `"en"` (default) — English
* - `"bn"` — Bengali
* - `"hi"` — Hindi
* @returns A new `BanglaDate` representing the current instant.
*
* @example
* const d = BanglaDate.now('bn');
* d.format('DD MMMM YYYY HH:mm:ss'); // e.g. "২৪ ফাল্গুন ১৪৩২ ১৪:৩০:০৫"
*/
static now(language?: Language): BanglaDate;
/**
* Parses a Bangla date string in the **`"DD MonthName YYYY"`** format and
* returns a new `BanglaDate` instance set to midnight UTC on that date.
*
* Parsing rules:
* - The three tokens must be separated by one or more whitespace characters.
* - `DD` — a positive integer day of month (e.g. `"1"` or `"15"`).
* - `MonthName` — one of the 12 English Bangla month names, case-insensitive
* (e.g. `"Boishakh"`, `"boishakh"`, `"BOISHAKH"`).
* - `YYYY` — a positive integer Bangla year (e.g. `"1432"`).
*
* Valid month names (case-insensitive):
* `Boishakh`, `Jyoishtho`, `Asharh`, `Shrabon`, `Bhadro`, `Ashwin`,
* `Kartik`, `Ogrohayon`, `Poush`, `Magh`, `Falgun`, `Chaitra`.
*
* @param dateString - A date string in `"DD MonthName YYYY"` format.
* @param language - Language for the returned instance's text output.
* Defaults to `"en"`.
* @returns A new `BanglaDate` at midnight UTC on the parsed Bangla date.
* @throws {BanglaDateParseError} When the string does not have exactly three
* whitespace-separated tokens, the month name is unrecognised, or the day
* or year tokens are not valid positive integers.
* @throws {BanglaDateRangeError} When the day exceeds the maximum for the
* given month (e.g. `"32 Boishakh 1432"` or `"31 Ashwin 1432"`).
*
* @example
* BanglaDate.parse('15 Boishakh 1432').toString();
* // "15 Boishakh 1432 BA"
*
* BanglaDate.parse('1 chaitra 1432', 'bn').toString();
* // "১ চৈত্র ১৪৩২ বঙ্গাব্দ"
*/
static parse(dateString: string, language?: Language): BanglaDate;
/**
* Returns `true` when the given **Gregorian** year is a leap year.
*
* Uses the standard proleptic Gregorian rule:
* - Divisible by 4 → leap, **except** centuries (÷100) which are
* only leap if also divisible by 400.
*
* > **Note:** Pass the Gregorian reference year, *not* the Bangla year.
* > Bangla leap-year determination (see `getMonthLengths`) tests the year
* > *following* the reference year because Falgun (month 11) falls in
* > mid-February to mid-March of that next Gregorian year.
*
* @param year - A full Gregorian year (e.g. `2024`).
* @returns `true` if `year` is a Gregorian leap year, `false` otherwise.
*
* @example
* BanglaDate.isLeapYear(2024); // true
* BanglaDate.isLeapYear(1900); // false (century, not ÷400)
* BanglaDate.isLeapYear(2000); // true (divisible by 400)
*/
static isLeapYear(year: number): boolean;
/**
* Returns a 12-element array of day-counts for the Bangla year whose
* **Pohela Boishakh** (1 Boishakh) falls on April 14 of `gregorianRefYear`.
*
* Per the Bangladesh National Calendar:
* - Months 1–5 (Boishakh–Bhadra) → **31 days** each = 155
* - Months 6–10 (Ashwin–Magh) → **30 days** each = 150
* - Month 11 (Falgun) → 29 days (common) or 30 (Bangla leap year)
* - Month 12 (Chaitra) → **30 days** always
*
* **Leap year rule:** The Bangla year straddles two Gregorian years.
* Falgun (month 11) falls in mid-February to mid-March of
* `gregorianRefYear + 1`, so the leap-year test is applied to
* `gregorianRefYear + 1`, not `gregorianRefYear` itself.
*
* Totals: 364 (common) / 365 (leap).
*
* @param gregorianRefYear - The Gregorian year in which Pohela Boishakh
* (April 14) of the target Bangla year falls (e.g. pass `2025` for
* Bangla year 1432).
* @returns An array `[31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29|30, 30]`
* indexed 0 (Boishakh) through 11 (Chaitra).
*
* @example
* BanglaDate.getMonthLengths(2024);
* // [31,31,31,31,31,30,30,30,30,30,30,30] — 2025 is leap → Falgun=30
*
* BanglaDate.getMonthLengths(2025);
* // [31,31,31,31,31,30,30,30,30,30,29,30] — 2026 is not leap → Falgun=29
*/
static getMonthLengths(gregorianRefYear: number): number[];
/**
* Creates a `BanglaDate` at **midnight UTC** for today's date.
*
* Time components are zeroed (`00:00:00.000 UTC`), making this suitable
* for date-only comparisons, calendar rendering, and any use case where
* the time of day is irrelevant. For the current instant with time
* preserved, use `now()` instead.
*
* @param language - Output language for all text-returning methods.
* - `"en"` (default) — English
* - `"bn"` — Bengali
* - `"hi"` — Hindi
* @returns A new `BanglaDate` representing today at `00:00:00.000 UTC`.
*
* @example
* BanglaDate.today('en').toString();
* // e.g. "24 Falgun 1432 BA"
*
* BanglaDate.today('bn').format('WWWW, DD MMMM YYYY');
* // e.g. "রবিবার, ২৪ ফাল্গুন ১৪৩২"
*/
static today(language?: Language): BanglaDate;
/**
* Creates a `BanglaDate` from explicit Bangla calendar components, set to
* midnight UTC on that date.
*
* This is the primary factory for constructing a `BanglaDate` when you
* already know the Bangla year, month, and day (e.g. from user input or
* a stored Bangla date string). Internally it converts the components to a
* Gregorian timestamp by offsetting from Pohela Boishakh (April 14 UTC).
*
* @param year - Full Bangla year (e.g. `1432`). Any positive integer.
* @param month - 1-indexed Bangla month number:
* `1`=Boishakh, `2`=Jyoishtho, `3`=Asharh, `4`=Shrabon, `5`=Bhadro,
* `6`=Ashwin, `7`=Kartik, `8`=Ogrohayon, `9`=Poush, `10`=Magh,
* `11`=Falgun, `12`=Chaitra.
* @param day - Day of the month (1-based). Must not exceed the length of
* the given month in the given year (see `getMonthLengths`).
* @param language - Output language for all text-returning methods.
* Defaults to `"en"`.
* @returns A new `BanglaDate` at midnight UTC on the specified Bangla date.
* @throws {BanglaDateRangeError} If `month` is not 1–12, `day` is less than
* 1, or `day` exceeds the maximum day count for the given month.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 1, 'en').toString();
* // "1 Boishakh 1432 BA" (= 2025-04-14 UTC)
*
* BanglaDate.fromBanglaDate(1432, 12, 30, 'bn').toString();
* // "৩০ চৈত্র ১৪৩২ বঙ্গাব্দ"
*/
static fromBanglaDate(year: number, month: number, day: number, language?: Language): BanglaDate;
/**
* Returns `true` when the given Bangla calendar components form a valid date.
*
* Validation checks (all must pass):
* 1. `year`, `month`, and `day` must all be integers
* (`Number.isInteger` is `true`).
* 2. `month` must be in the range 1–12.
* 3. `day` must be at least 1.
* 4. `day` must not exceed the maximum day count for `month` in `year`
* (accounts for Bangla leap years where Chaitra = 31 days).
*
* This is a pure validation helper — it does **not** create a `BanglaDate`
* instance. Use it to guard user input before calling `fromBanglaDate()`.
*
* @param year - Bangla year to validate (e.g. `1432`).
* @param month - 1-indexed Bangla month (1 = Boishakh … 12 = Chaitra).
* @param day - Day of the month.
* @returns `true` if the combination is a valid Bangla date, `false` otherwise.
*
* @example
* BanglaDate.isValidBanglaDate(1432, 1, 31); // true (Boishakh has 31 days)
* BanglaDate.isValidBanglaDate(1432, 6, 31); // false (Ashwin has only 30 days)
* BanglaDate.isValidBanglaDate(1432, 0, 1); // false (month 0 is invalid)
* BanglaDate.isValidBanglaDate(1432, 1, 1.5); // false (day is not an integer)
*/
static isValidBanglaDate(year: number, month: number, day: number): boolean;
/**
* Returns `true` when this instance represents a valid Bangla date.
*
* An instance can be invalid if:
* - The underlying Gregorian `Date` has an invalid timestamp (`NaN`).
* - The computed Bangla month index is outside 0–11 (should not occur
* under normal construction, but may arise from manual manipulation).
* - The computed Bangla day is less than 1 or greater than the maximum
* day count for the month (e.g. > 30 for Ashwin, or > 30/31 for Chaitra).
*
* @returns `true` if this date is valid, `false` otherwise.
*
* @example
* new BanglaDate(new Date('invalid')).isValid(); // false
* BanglaDate.fromBanglaDate(1432, 1, 15).isValid(); // true
*/
isValid(): boolean;
/**
* Returns `true` when this date is **strictly before** `other`.
*
* Comparison is performed on the underlying millisecond timestamps
* (UTC), so time-of-day is taken into account. If you want a
* date-only comparison, call `isBefore` on `today()`-normalised
* instances, or use `isSame`/`diff` with `granularity: 'day'`.
*
* @param other - The `BanglaDate` to compare against.
* @returns `true` if `this` is earlier than `other`, `false` otherwise
* (including when they are equal).
*
* @example
* const a = BanglaDate.fromBanglaDate(1432, 1, 1);
* const b = BanglaDate.fromBanglaDate(1432, 6, 1);
* a.isBefore(b); // true
* b.isBefore(a); // false
* a.isBefore(a); // false (equal, not strictly before)
*/
isBefore(other: BanglaDate): boolean;
/**
* Returns `true` when this date is **strictly after** `other`.
*
* Comparison is performed on the underlying millisecond timestamps
* (UTC), so time-of-day is taken into account.
*
* @param other - The `BanglaDate` to compare against.
* @returns `true` if `this` is later than `other`, `false` otherwise
* (including when they are equal).
*
* @example
* const a = BanglaDate.fromBanglaDate(1432, 1, 1);
* const b = BanglaDate.fromBanglaDate(1432, 6, 1);
* b.isAfter(a); // true
* a.isAfter(b); // false
* a.isAfter(a); // false (equal, not strictly after)
*/
isAfter(other: BanglaDate): boolean;
/**
* Returns `true` when this date and `other` are equal at the given
* granularity level.
*
* - `"year"` — only the Bangla year must match.
* - `"month"` — both the Bangla year **and** month index must match.
* - `"day"` — year, month, **and** day must all match (default).
*
* Note: the comparison is on Bangla calendar fields, not on raw timestamps.
* Two instances created from different times on the same Bangla calendar day
* will still return `true` for `isSame(other, 'day')`.
*
* @param other - The `BanglaDate` to compare against.
* @param granularity - How precisely to compare. Defaults to `'day'`.
* @returns `true` if the dates are equal at the specified granularity.
*
* @example
* const a = BanglaDate.fromBanglaDate(1432, 3, 10);
* const b = BanglaDate.fromBanglaDate(1432, 3, 25);
* const c = BanglaDate.fromBanglaDate(1433, 3, 10);
*
* a.isSame(b, 'year'); // true (same year 1432)
* a.isSame(b, 'month'); // true (same year + month)
* a.isSame(b, 'day'); // false (different days)
* a.isSame(c, 'year'); // false (different years)
*/
isSame(other: BanglaDate, granularity?: "day" | "month" | "year"): boolean;
/**
* Returns a **new** `BanglaDate` shifted forward by `amount` of the given
* `unit`. This instance is **not** mutated (immutable operation).
*
* Pass a negative `amount` to shift into the past. Alternatively use
* `subtract()` for a more readable API.
*
* **Day addition** is exact: it simply adds `amount × 86 400 000 ms` to
* the underlying timestamp, so the time-of-day is always preserved.
*
* **Month / year addition** computes the new Bangla calendar position and
* then re-applies the original time-of-day offset. When the current day
* exceeds the maximum day count of the target month, it is **clamped** to
* that month's last day (e.g. 31 Boishakh + 5 months = 30 Ashwin, because
* Ashwin has only 30 days).
*
* @param amount - Number of units to add. Negative values subtract.
* @param unit - Unit of addition. Defaults to `"days"`.
* - `"days"` — calendar days (exact millisecond arithmetic)
* - `"months"` — Bangla calendar months; handles year roll-over automatically
* - `"years"` — Bangla calendar years
* @returns A new `BanglaDate` shifted by the specified amount.
*
* @example
* const d = BanglaDate.fromBanglaDate(1432, 1, 15);
* d.add(10, 'days').toString(); // "25 Boishakh 1432 BA"
* d.add(2, 'months').toString(); // "15 Asharh 1432 BA"
* d.add(1, 'years').toString(); // "15 Boishakh 1433 BA"
* d.add(-3, 'days').toString(); // "12 Boishakh 1432 BA"
*/
add(amount: number, unit?: "days" | "months" | "years"): BanglaDate;
/**
* Returns a **new** `BanglaDate` shifted **backward** by `amount` of the
* given `unit`. This instance is **not** mutated.
*
* This is a convenience alias for `add(-amount, unit)`. All behaviour
* (day clamping, time-of-day preservation, year roll-over) is identical
* to `add()`.
*
* @param amount - Number of units to subtract (positive number = go back).
* @param unit - Unit of subtraction. Defaults to `"days"`.
* - `"days"` — calendar days
* - `"months"` — Bangla calendar months
* - `"years"` — Bangla calendar years
* @returns A new `BanglaDate` shifted backward by the specified amount.
*
* @example
* const d = BanglaDate.fromBanglaDate(1432, 6, 15);
* d.subtract(1, 'months').toString(); // "15 Bhadro 1432 BA"
* d.subtract(7, 'days').toString(); // "8 Ashwin 1432 BA"
* d.subtract(1, 'years').toString(); // "15 Ashwin 1431 BA"
*/
subtract(amount: number, unit?: "days" | "months" | "years"): BanglaDate;
/**
* Calculates the **signed** difference between this date and `other`.
*
* - A **positive** result means `this` is **after** `other`.
* - A **negative** result means `this` is **before** `other`.
* - Zero means the dates are equal at the requested unit.
*
* **`"days"`** — divides the raw millisecond difference by 86 400 000 and
* floors the result, so partial days are truncated.
*
* **`"months"`** — counts completed Bangla calendar months. The result is
* adjusted so that a partial trailing month is not counted (e.g. Jan 31 →
* Feb 28 = 0 full months, not 1).
*
* **`"years"`** — counts completed Bangla calendar years, using the
* month and day to decide whether the anniversary has been passed.
*
* @param other - The reference `BanglaDate` to subtract from `this`.
* @param unit - Unit for the result. Defaults to `"days"`.
* @returns Signed integer difference in the requested unit.
*
* @example
* const start = BanglaDate.fromBanglaDate(1432, 1, 1);
* const end = BanglaDate.fromBanglaDate(1432, 3, 15);
*
* end.diff(start, 'days'); // 76
* end.diff(start, 'months'); // 2
* start.diff(end, 'days'); // -76 (negative — start is before end)
*
* const a = BanglaDate.fromBanglaDate(1430, 5, 20);
* const b = BanglaDate.fromBanglaDate(1432, 3, 10);
* b.diff(a, 'years'); // 1 (only 1 full year has elapsed)
*/
diff(other: BanglaDate, unit?: "days" | "months" | "years"): number;
/**
* Returns a **new** `BanglaDate` set to the **first day** of the current
* Bangla month, at midnight UTC. This instance is not mutated.
*
* Equivalent to `BanglaDate.fromBanglaDate(year, month, 1)`.
*
* @returns A new `BanglaDate` at day 1 of this month.
*
* @example
* BanglaDate.fromBanglaDate(1432, 3, 20).startOfMonth().toString();
* // "1 Asharh 1432 BA"
*/
startOfMonth(): BanglaDate;
/**
* Returns a **new** `BanglaDate` set to the **last day** of the current
* Bangla month, at midnight UTC. This instance is not mutated.
*
* The last day is determined by `getMonthLengths()` and correctly handles
* Bangla leap years (Chaitra = 30 or 31 days).
*
* @returns A new `BanglaDate` at the last day of this month.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 5).endOfMonth().toString();
* // "31 Boishakh 1432 BA" (Boishakh always has 31 days)
*
* BanglaDate.fromBanglaDate(1432, 6, 1).endOfMonth().toString();
* // "30 Ashwin 1432 BA" (Ashwin has 30 days)
*/
endOfMonth(): BanglaDate;
/**
* Returns a **new** `BanglaDate` set to **1 Boishakh** (the first day of
* the Bangla year) at midnight UTC. This instance is not mutated.
*
* @returns A new `BanglaDate` at 1 Boishakh of this Bangla year.
*
* @example
* BanglaDate.fromBanglaDate(1432, 8, 15).startOfYear().toString();
* // "1 Boishakh 1432 BA" (= 2025-04-14 UTC)
*/
startOfYear(): BanglaDate;
/**
* Returns a **new** `BanglaDate` set to the **last day of Chaitra** (the
* final day of the Bangla year) at midnight UTC. This instance is not mutated.
*
* Chaitra has 30 days in a common year and 31 days in a Bangla leap year
* (when the following Gregorian year is a leap year).
*
* @returns A new `BanglaDate` at 30 or 31 Chaitra of this Bangla year.
*
* @example
* BanglaDate.fromBanglaDate(1432, 3, 1).endOfYear().toString();
* // "30 Chaitra 1432 BA" (2026 is not a Gregorian leap year)
*/
endOfYear(): BanglaDate;
/**
* Returns the **1-based day number** within the Bangla year.
*
* Day 1 = 1 Boishakh. The maximum value is 365 in a common year and
* 366 in a Bangla leap year (when Chaitra has 31 days).
*
* @returns Integer in the range 1–366 indicating the ordinal day of the year.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 1).getDayOfYear(); // 1
* BanglaDate.fromBanglaDate(1432, 2, 1).getDayOfYear(); // 32 (after 31-day Boishakh)
* BanglaDate.fromBanglaDate(1432, 6, 1).getDayOfYear(); // 156 (after 5×31 days)
*/
getDayOfYear(): number;
/**
* Returns the **Bengali season (Ritu)** name for the current month in
* the instance's language.
*
* The Bengali calendar divides the year into six two-month seasons:
*
* | Months | en | bn | hi |
* |-------------------------|----------|--------|----------|
* | Boishakh – Jyoishtho | Grishmo | গ্রীষ্ম | ग्रीष्म |
* | Asharh – Shrabon | Borsha | বর্ষা | वर्षा |
* | Bhadro – Ashwin | Shorot | শরৎ | शरद |
* | Kartik – Ogrohayon | Hemonto | হেমন্ত | हेमन्त |
* | Poush – Magh | Sheet | শীত | शीत |
* | Falgun – Chaitra | Boshonto | বসন্ত | वसन्त |
*
* @returns The season name in the instance's language.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 1, 'en').getRitu(); // "Grishmo"
* BanglaDate.fromBanglaDate(1432, 1, 1, 'bn').getRitu(); // "গ্রীষ্ম"
* BanglaDate.fromBanglaDate(1432, 9, 1, 'en').getRitu(); // "Sheet"
*/
getRitu(): string;
/**
* Returns the **era label** for the Bangla calendar in the instance's language.
*
* The Bangla era is called *Bangabda* (বঙ্গাব্দ). Its epoch is traditionally
* placed at 594 CE. This label should not be confused with the Gregorian
* BC/AD era used by `Intl.DateTimeFormat`.
*
* | Language | Era label |
* |----------|-------------|
* | `en` | `"BA"` |
* | `bn` | `"বঙ্গাব্দ"` |
* | `hi` | `"बंगाब्द"` |
*
* @returns The era label string in the instance's language.
*
* @example
* BanglaDate.today('en').getEra(); // "BA"
* BanglaDate.today('bn').getEra(); // "বঙ্গাব্দ"
* BanglaDate.today('hi').getEra(); // "बंगाब्द"
*/
getEra(): string;
/**
* Returns the name of a **major Bengali festival** that falls on this date,
* or an empty string if no recognised festival occurs today.
*
* Festival dates follow the **revised Bangladesh National Calendar**:
*
* | Bangla date | en |
* |---------------------------|---------------------------------|
* | 1 Boishakh | Pohela Boishakh (Bengali New Year) |
* | 25 Boishakh | Rabindra Jayanti |
* | 11 Jyoishtho | Nazrul Jayanti |
* | Last day of Chaitra | Chaitra Sangkranti (Year end) |
*
* The returned string is in the instance's language (`en` / `bn` / `hi`).
* Chaitra Sangkranti is computed dynamically (30th or 31st Chaitra
* depending on whether it is a Bangla leap year).
*
* @returns The festival name in the instance's language, or `""` if none.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 1, 'en').getFestival();
* // "Pohela Boishakh (Bengali New Year)"
*
* BanglaDate.fromBanglaDate(1432, 1, 1, 'bn').getFestival();
* // "পহেলা বৈশাখ (নববর্ষ)"
*
* BanglaDate.fromBanglaDate(1432, 3, 1, 'en').getFestival();
* // "" (no festival on 1 Asharh)
*/
getFestival(): string;
/**
* Returns a **human-readable relative time string** comparing this date to
* today (midnight UTC), in the instance's language.
*
* **Thresholds:**
* - 0 days difference → `"today"` / `"আজ"` / `"आज"`
* - 1 day difference → `"yesterday"`/`"tomorrow"` (language-aware)
* - < 30 days → `"N days ago"` / `"in N days"`
* - 30+ days but < 12 months → `"N months ago"` / `"in N months"`
* (falls back to days if no full Bangla month boundary has been crossed)
* - 12+ months → `"N years ago"` / `"in N years"`
*
* @returns A localised relative time string in the instance's language.
*
* @example
* // Assuming today is 24 Falgun 1432
* BanglaDate.fromBanglaDate(1432, 2, 24).relativeTime(); // "in 1 month"
* BanglaDate.fromBanglaDate(1432, 2, 23).relativeTime(); // "1 month ago" (approx)
* BanglaDate.today('bn').relativeTime(); // "আজ"
* BanglaDate.today().add(1, 'days').relativeTime(); // "tomorrow"
* BanglaDate.today().subtract(1, 'days').relativeTime(); // "yesterday"
* BanglaDate.fromBanglaDate(1430, 1, 1).relativeTime(); // "2 years ago"
*/
relativeTime(): string;
/**
* Returns a **defensive copy** of the underlying Gregorian `Date` object.
*
* Modifying the returned `Date` does not affect this `BanglaDate` instance.
* Use this when you need to pass the date to APIs that expect a native `Date`,
* such as `Date.prototype.toISOString()` or third-party date libraries.
*
* @returns A new `Date` instance with the same Unix timestamp as this
* `BanglaDate`.
*
* @example
* const d = BanglaDate.fromBanglaDate(1432, 1, 1);
* d.toGregorian().toISOString(); // "2025-04-14T00:00:00.000Z"
*/
toGregorian(): Date;
/**
* Returns a **plain-object snapshot** of this date suitable for
* `JSON.stringify` serialisation.
*
* All numeric fields are raw integers (not localised digit strings).
* The `era` field is the language-aware era label from `getEra()`.
*
* Shape:
* ```json
* {
* "year": 1432,
* "month": 1,
* "day": 5,
* "era": "BA",
* "hours": 6,
* "minutes": 30,
* "seconds": 0,
* "milliseconds": 0
* }
* ```
*
* @returns A plain object representation of this `BanglaDate`.
*
* @example
* const d = BanglaDate.fromBanglaDate(1432, 1, 5, 'bn');
* JSON.stringify(d);
* // '{"year":1432,"month":1,"day":5,"era":"বঙ্গাব্দ","hours":0,...}'
*/
toJSON(): {
year: number;
month: number;
day: number;
era: string;
hours: number;
minutes: number;
seconds: number;
milliseconds: number;
};
/**
* Returns a **new, independent** `BanglaDate` that is an exact copy of
* this instance — same Gregorian timestamp, same language setting.
*
* Use this before passing a `BanglaDate` to code that may mutate it, or
* when you need to branch two date calculations from the same starting point.
*
* @returns A new `BanglaDate` identical to `this`.
*
* @example
* const a = BanglaDate.fromBanglaDate(1432, 1, 15, 'bn');
* const b = a.clone();
* b.add(10, 'days'); // does not affect `a` (both are immutable anyway)
* a.isSame(b); // true — same date
*/
clone(): BanglaDate;
/**
* Allows the instance to be used directly in **numeric and string contexts**
* without an explicit method call.
*
* - **Numeric hint** (e.g. `+d`, `d - other`, comparison operators) →
* returns the Unix timestamp in milliseconds (same as `getTime()`).
* - **String hint** (e.g. template literals `` `${d}` ``, string
* concatenation) → returns the `toString()` value.
* - **Default hint** → returns the `toString()` value.
*
* @param hint - The type hint provided by the JS engine: `"number"`,
* `"string"`, or `"default"`.
* @returns The Unix timestamp (ms) for numeric hint, otherwise the
* localised date string from `toString()`.
*
* @example
* const d = BanglaDate.fromBanglaDate(1432, 1, 1, 'bn');
* +d; // 1744588800000 (Unix ms timestamp)
* `Date: ${d}`; // "Date: ১ বৈশাখ ১৪৩২ বঙ্গাব্দ"
*/
[Symbol.toPrimitive](hint: string): string | number;
/**
* Returns the **full localised date string** including the era label.
*
* Format: `"<day> <monthName> <year> <era>"`
*
* All digit characters are localised to the instance's language:
* - `en` → Latin digits, English month names: `"15 Boishakh 1432 BA"`
* - `bn` → Bengali digits, Bengali month names: `"১৫ বৈশাখ ১৪৩২ বঙ্গাব্দ"`
* - `hi` → Devanagari digits, Hindi month names: `"१५ बैशाख १४३२ बंगाब्द"`
*
* This method is called automatically when the instance is coerced to a
* string (e.g. in template literals or string concatenation).
*
* @returns Localised date string in `"DD MMMM YYYY era"` format.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 15, 'en').toString();
* // "15 Boishakh 1432 BA"
*
* BanglaDate.fromBanglaDate(1432, 1, 15, 'bn').toString();
* // "১৫ বৈশাখ ১৪৩২ বঙ্গাব্দ"
*/
toString(): string;
/**
* Returns a **short date string with the weekday** name, without the era.
*
* Format: `"<weekdayFull>, <day> <monthFull> <year>"`
*
* The weekday and month names are in the instance's language. Digits are
* localised. The year is the full 4-digit Bangla year.
*
* @returns Localised date string in `"WWWW, DD MMMM YYYY"` format.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 14, 'en').toDateString();
* // "Monday, 14 Boishakh 1432"
*
* BanglaDate.fromBanglaDate(1432, 1, 14, 'bn').toDateString();
* // "সোমবার, ১৪ বৈশাখ ১৪৩২"
*/
toDateString(): string;
/**
* Returns the day of the Bangla month as a raw number.
* Range: 1–31 (months 1–5 can have 31; Chaitra has 30 or 31 in a leap year).
* @returns Bangla day of month (1-based).
*/
getDate(): number;
/**
* Returns the UTC weekday index of the underlying Gregorian date.
* The Bangla calendar shares the same 7-day week as the Gregorian calendar.
* @returns `0` = Sunday, `1` = Monday, … `6` = Saturday.
*/
getDay(): number;
/**
* Returns the full 4-digit Bangla year.
* @returns e.g. `1432`.
*/
getFullYear(): number;
/**
* Returns the UTC hour component of the underlying timestamp.
* @returns Integer in the range 0–23.
*/
getHours(): number;
/**
* Returns the UTC milliseconds component of the underlying timestamp.
* @returns Integer in the range 0–999.
*/
getMilliseconds(): number;
/**
* Returns the UTC minutes component of the underlying timestamp.
* @returns Integer in the range 0–59.
*/
getMinutes(): number;
/**
* Returns the 1-indexed Bangla month number.
* @returns `1` = Boishakh, `2` = Jyoishtho, … `12` = Chaitra.
*/
getMonth(): number;
/**
* Returns the UTC seconds component of the underlying timestamp.
* @returns Integer in the range 0–59.
*/
getSeconds(): number;
/**
* Returns the Unix timestamp (milliseconds since 1970-01-01T00:00:00Z).
* Identical to the value returned by the underlying `Date.prototype.getTime()`.
* Useful for comparisons, storage, and interop with native Date APIs.
* @returns Milliseconds since Unix epoch.
*/
getTime(): number;
/**
* Returns the host's timezone offset from UTC, in minutes.
* Mirrors `Date.prototype.getTimezoneOffset()`.
* A positive value means UTC is ahead (e.g. UTC−5 → `300`);
* a negative value means UTC is behind (e.g. UTC+6 → `-360`).
* @returns Timezone offset in minutes.
*/
getTimezoneOffset(): number;
/** Returns the UTC day-of-month of the underlying Gregorian date (1-based). */
getUTCDate(): number;
/** Returns the UTC weekday of the underlying Gregorian date (0 = Sunday … 6 = Saturday). */
getUTCDay(): number;
/** Returns the UTC 4-digit Gregorian year of the underlying timestamp. */
getUTCFullYear(): number;
/** Returns the UTC hour (0–23) of the underlying timestamp. */
getUTCHours(): number;
/** Returns the UTC milliseconds (0–999) of the underlying timestamp. */
getUTCMilliseconds(): number;
/** Returns the UTC minutes (0–59) of the underlying timestamp. */
getUTCMinutes(): number;
/** Returns the UTC **Gregorian** month index (0–11) of the underlying timestamp. Not a Bangla field. */
getUTCMonth(): number;
/** Returns the UTC seconds (0–59) of the underlying timestamp. */
getUTCSeconds(): number;
/**
* Returns the **full 4-digit Bangla year**.
*
* This is an alias of `getFullYear()`. Unlike the deprecated standard
* `Date.prototype.getYear()` (which returns the year minus 1900),
* this method always returns the complete year (e.g. `1432`, not `432`).
*
* @returns Full Bangla year (e.g. `1432`).
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 1).getYear(); // 1432
*/
getYear(): number;
/**
* Returns the full (long) month name in the instance's language.
* Internal helper — delegates to `getFormattedMonthName('long')`.
* @internal
*/
private getMonthName;
/**
* Returns the full (long) weekday name in the instance's language.
* Internal helper — delegates to `getWeekDayFormat('long')`.
* @internal
*/
private getWeekDay;
/**
* Returns an **ISO 8601-like string** using Bangla calendar coordinates
* instead of Gregorian ones.
*
* Format: `"YYYY-MM-DDThh:mm:ss.mmmZ"`
* where `YYYY`, `MM`, and `DD` are the Bangla year, month, and day;
* the time portion (`hh:mm:ss.mmm`) is always in UTC.
*
* > Note: This string uses Bangla calendar values and is therefore **not**
* > a standards-compliant ISO 8601 Gregorian date string. To obtain a
* > standards-compliant string, call `toGregorian().toISOString()`.
*
* @returns ISO-like string, e.g. `"1432-01-14T00:00:00.000Z"`.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 14).toISOString();
* // "1432-01-14T00:00:00.000Z"
*
* // Compare with the Gregorian equivalent:
* BanglaDate.fromBanglaDate(1432, 1, 14).toGregorian().toISOString();
* // "2025-04-14T00:00:00.000Z"
*/
toISOString(): string;
/**
* Returns a localised **date-only** string using `Intl.DateTimeFormat` formatting
* but substituting all Gregorian fields with their Bangla calendar equivalents.
*
* Mirrors the signature of `Date.prototype.toLocaleDateString`.
*
* @param locales - A BCP 47 locale string or array. Supported base languages:
* `"en"` / `"en-US"`, `"bn"` / `"bn-BD"`, `"hi"` / `"hi-IN"`.
* Defaults to the language set on the instance.
* @param options - An `Intl.DateTimeFormatOptions` object. When omitted,
* defaults to `{ year: 'numeric', month: 'numeric', day: 'numeric' }`.
* The `timeZone` property may be any IANA timezone string (e.g.
* `"Asia/Dhaka"`). When a non-UTC timezone is provided, the Bangla
* calendar date fields are recomputed for that local date.
* @returns A formatted date string, e.g. `"14/4/1432"` or `"১৪/৪/১৪৩২"`.
*
* @example
* const d = BanglaDate.fromBanglaDate(1432, 1, 14, 'en');
* d.toLocaleDateString('en-US'); // "4/14/1432" (US order)
* d.toLocaleDateString('bn-BD', { month: 'long' }); // "১৪ বৈশাখ ১৪৩২"
*/
toLocaleDateString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
/**
* Returns a **localised UTC time string** in `HH:mm:ss UTC` format.
*
* Hour, minute, and second digits are rendered in the instance's
* language script (Latin / Bengali / Devanagari). The timezone label
* is always the literal string `" UTC"`.
*
* @returns Localised time string, e.g.
* - `en`: `"08:30:05 UTC"`
* - `bn`: `"০৮:৩০:০৫ UTC"`
* - `hi`: `"०८:३०:०५ UTC"`
*
* @example
* const d = new BanglaDate(new Date('2025-04-14T08:30:05Z'), 'bn');
* d.toTimeString(); // "০৮:৩০:০৫ UTC"
*/
toTimeString(): string;
/**
* Zero-pads a number or numeric string to at least 2 digits.
* Used internally by `format()` for `MM`, `DD`, `HH`, `mm`, `ss` tokens.
* @param num - The value to pad.
* @returns A string of at least 2 characters (e.g. `"05"` for `5`).
* @internal
*/
private formatNumber;
/**
* Returns the AM/PM (or Bengali/Hindi equivalent) day-period string
* for the given UTC hour.
*
* | Language | AM | PM |
* |----------|--------------|---------------|
* | `en` | `"AM"` | `"PM"` |
* | `bn` | `"পূর্বাহ্ণ"` | `"অপরাহ্ণ"` |
* | `hi` | `"पूर्वाह्न"` | `"अपराह्न"` |
*
* @param hour - UTC hour (0–23) as a number or numeric string.
* @returns The localised day-period label.
* @internal
*/
private getAMPM;
/**
* Formats the Bangla date using a custom format string inspired by Moment.js / Day.js.
*
* Digits in the output are automatically localised to the language set on
* the instance (`"en"`, `"bn"`, or `"hi"`).
*
* ### Format Tokens
*
* | Token | Output example | Description |
* |----------|-----------------------------|---------------------------------------------|
* | `YYYY` | `1432` | 4-digit Bangla year |
* | `YY` | `32` | 2-digit Bangla year |
* | `MMMM` | `Boishakh` / `বৈশাখ` | Full month name |
* | `MMM` | `Boi` / `বৈশা` | Short month name (3–4 chars) |
* | `MM` | `01` | Zero-padded 2-digit month (01–12) |
* | `M` | `1` | Month without padding (1–12) |
* | `DD` | `05` | Zero-padded day of month (01–31) |
* | `D` | `5` | Day of month without padding (1–31) |
* | `Do` | `1st` / `পহেলা` / `पहला` | Ordinal day of month |
* | `WWWW` | `Sunday` / `রবিবার` | Full weekday name |
* | `WWW` | `Sun` / `রবি` | Short weekday name |
* | `WW` | `00` | Zero-padded weekday index (00=Sun…06=Sat) |
* | `W` | `0` | Weekday index (0=Sun…6=Sat) |
* | `HH` | `08` | Zero-padded 24-hour (00–23) |
* | `H` | `8` | 24-hour without padding (0–23) |
* | `mm` | `05` | Zero-padded minutes (00–59) |
* | `m` | `5` | Minutes without padding (0–59) |
* | `ss` | `09` | Zero-padded seconds (00–59) |
* | `s` | `9` | Seconds without padding (0–59) |
* | `AM/PM` | `AM` / `PM` | Day period in uppercase |
* | `era` | `BA` / `বঙ্গাব্দ` | Era label |
*
* ### Escape Sequences
* Wrap literal text in square brackets `[...]` to prevent it from being
* treated as format tokens or having its digits localised.
*
* @param formatString - A format string composed of the tokens listed above
* and optional literal sections enclosed in `[...]`.
* @returns The formatted date string with localised digits.
* @throws {BanglaDateError} If more than 26 `[...]` escape sections are used.
*
* @example
* const d = BanglaDate.fromBanglaDate(1432, 1, 5, 'en');
* d.format('DD MMMM YYYY'); // "05 Boishakh 1432"
* d.format('YYYY-MM-DD'); // "1432-01-05"
* d.format('Do MMMM YYYY [era]'); // "5th Boishakh 1432 era" ("era" literal)
* d.format('Do MMMM YYYY era'); // "5th Boishakh 1432 BA" (era token)
* d.format('WWWW, DD MMMM YYYY'); // "Monday, 05 Boishakh 1432"
* d.format('HH:mm:ss AM/PM'); // "06:00:00 AM"
*
* // Bengali output
* const bn = BanglaDate.fromBanglaDate(1432, 1, 5, 'bn');
* bn.format('DD MMMM YYYY'); // "০৫ বৈশাখ ১৪৩২"
*/
format(formatString: string): string;
/**
* Returns the Bangla month name in the instance's language and the
* requested display format.
*
* | Format | Example (en) | Example (bn) |
* |-----------|----------------|----------------|
* | `long` | `"Boishakh"` | `"বৈশাখ"` |
* | `short` | `"Boi"` | `"বৈশা"` |
* | `narrow` | `"B"` | `"বৈ"` |
*
* Called internally by `toString()`, `toDateString()`, `format()` (for
* `MMMM` / `MMM`), and `_applyLocale()` (for named-month locale output).
*
* @param format - Display format. Defaults to `"long"`.
* @returns The month name string.
* @internal
*/
private getFormattedMonthName;
/**
* Returns a localised **date and time** string using `Intl.DateTimeFormat`
* formatting with all Gregorian calendar fields replaced by Bangla equivalents.
*
* Mirrors the signature of `Date.prototype.toLocaleString`.
*
* @param locales - A BCP 47 locale string or array. Supported base languages:
* `"en"` / `"en-US"`, `"bn"` / `"bn-BD"`, `"hi"` / `"hi-IN"`.
* Defaults to the language set on the instance.
* @param options - An `Intl.DateTimeFormatOptions` object. When omitted,
* defaults to `{ year, month, day, hour, minute, second: 'numeric' }`.
* The `timeZone` property may be any IANA timezone string (e.g.
* `"Asia/Dhaka"`). When a non-UTC timezone is provided, the Bangla
* calendar date fields are recomputed for that local date.
* @returns A formatted date-time string, e.g. `"14/4/1432, 6:00:00 AM"` or
* `"১৪/৪/১৪৩২, ৬:০০:০০ AM"`.
*
* @example
* const d = BanglaDate.fromBanglaDate(1432, 1, 14, 'bn');
* d.toLocaleString('bn-BD'); // "১৪/৪/১৪৩২, ৬:০০:০০ AM"
* d.toLocaleString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
* // "Monday, Boishakh 14, 1432"
*/
toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
/**
* Returns a **localised time-only string** using `Intl.DateTimeFormat`
* formatting. Mirrors the signature of `Date.prototype.toLocaleTimeString`.
*
* @param locales - A BCP 47 locale string or array. Supported base languages:
* `"en"` / `"en-US"`, `"bn"` / `"bn-BD"`, `"hi"` / `"hi-IN"`.
* Defaults to the language set on the instance.
* @param options - An `Intl.DateTimeFormatOptions` object. When omitted,
* defaults to `{ hour: 'numeric', minute: 'numeric', second: 'numeric' }`.
* The `timeZone` property may be any IANA timezone string.
* @returns A formatted time string, e.g. `"6:00:00 AM"` or `"৬:০০:০০ AM"`.
*
* @example
* const d = new BanglaDate(new Date('2025-04-14T06:30:00Z'), 'bn');
* d.toLocaleTimeString('bn-BD'); // "৬:৩০:০০ AM"
* d.toLocaleTimeString('en-US'); // "6:30:00 AM"
* d.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }); // "06:30 AM"
*/
toLocaleTimeString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
/**
* Shared implementation for `toLocaleDateString`, `toLocaleString`, and
* `toLocaleTimeString`.
*
* Uses `Intl.DateTimeFormat.formatToParts()` with `timeZone: "UTC"` so that
* the formatter and the UTC-based Bangla date components are always in sync,
* regardless of the host timezone. Each part is substituted with the
* corresponding Bangla value before being re-joined, which correctly handles
* numeric fields, month/weekday names, day-period tokens, and literal
* separators in a single pass — eliminating all fragile string-search
* replacements and post-processing loops.
*
* @param locales - A BCP 47 locale string or array passed directly from the
* public method. Only `"en"`, `"bn"`, `"hi"` (and their region variants
* such as `"en-US"`, `"bn-BD"`, `"hi-IN"`) are supported. If `undefined`,
* the instance's own language is used as the fallback.
* @param options - An `Intl.DateTimeFormatOptions` object controlling which
* fields appear in the output (e.g. `{ year: 'numeric', month: 'long' }`).
* The `timeZone` property may be any IANA timezone string (e.g.
* `"Asia/Dhaka"`, `"America/New_York"`). When a non-UTC timezone is
* supplied, the Bangla calendar date fields (year, month, day, weekday)
* are recomputed from the timezone-local Gregorian date so the output
* is consistent with the displayed local time.
* @returns The formatted string with all Gregorian calendar fields replaced
* by their Bangla equivalents, and digits localised to the resolved script.
* @throws {BanglaDateError} If the resolved locale is not one of the three
* supported languages.
* @internal
*/
private _applyLocale;
/**
* Returns the **ordinal form** of the Bangla day-of-month in the
* instance's language.
*
* Rules by language:
*
* **English (`en`)** — standard English ordinal suffixes:
* - `1st`, `2nd`, `3rd`, `4th`–`20th` → `th`
* - Exception: `11th`, `12th`, `13th` always use `th` (not `st`/`nd`/`rd`)
*
* **Bengali (`bn`)** — traditional forms:
* - 1 → পহেলা, 2 → দোসরা, 3 → তেসরা, 4 → চৌঠা
* - 5–18 → `Nই` (e.g. ৫ই, ১৫ই)
* - 19–31 → `Nশে` (e.g. ১৯শে, ৩১শে)
*
* **Hindi (`hi`)** — traditional ordinal forms:
* - 1 → पहला, 2 → दूसरा, 3 → तीसरा, 4 → चौथा
* - 5–20 → `Nवाँ` (e.g. ५वाँ, २०वाँ)
* - 21+ → `Nवें` (e.g. २१वें, ३१वें)
*
* Digits in the compound forms (e.g. `৫ই`) are localised to the
* instance's script.
*
* @returns The ordinal day string in the instance's language.
*
* @example
* BanglaDate.fromBanglaDate(1432, 1, 1, 'en').getOrdinalDate(); // "1st"
* BanglaDate.fromBanglaDate(1432, 1, 2, 'en').getOrdinalDate(); // "2nd"
* BanglaDate.fromBanglaDate(1432, 1, 11, 'en').getOrdinalDate(); // "11th"
* BanglaDate.fromBanglaDate(1432, 1, 1, 'bn').getOrdinalDate(); // "পহেলা"
* BanglaDate.fromBanglaDate(1432, 1, 5, 'bn').getOrdina