@subrotosaha/bangla-date
v1.9.0
Published
A simple utility package for string manipulation in JavaScript.
Maintainers
Readme
@subrotosaha/bangla-date
A zero-dependency TypeScript library for working with the Bangla (Bengali) calendar (Bangabda / বঙ্গাব্দ). It converts Gregorian dates to Bangla calendar dates, formats them in English, Bengali, and Hindi, and provides a rich set of arithmetic, comparison, and formatting utilities.
Table of Contents
Features
- Convert any Gregorian
Dateto the Bangla calendar (revised Bangladesh National Calendar, Pohela Boishakh = April 14 UTC). - Output in English (
en), Bengali (bn), or Hindi (hi) — including localised digits and month/weekday names. - Arithmetic:
add(),subtract(),diff()for days, months, and years. - Comparison:
isBefore(),isAfter(),isSame()with year/month/day granularity. - Start/end of month and year helpers.
- Season (
getRitu()), era (getEra()), ordinal date (getOrdinalDate()), festivals (getFestival()), and relative time (relativeTime()). format()with a rich token set (see Format Tokens).Intl.DateTimeFormat-poweredtoLocaleDateString(),toLocaleString(),toLocaleTimeString().- Parse a Bangla date string back to a
BanglaDateviaBanglaDate.parse(). - Full leap-year support (Chaitra = 31 days when the next Gregorian year is a leap year).
- Zero runtime dependencies.
Installation
npm install @subrotosaha/bangla-dateQuick Start
import BanglaDate from "@subrotosaha/bangla-date";
// Today's date in English
const today = BanglaDate.today("en");
console.log(today.toString());
// e.g. "24 Falgun 1432 BA"
// Today in Bengali
const todayBN = BanglaDate.today("bn");
console.log(todayBN.toString());
// e.g. "২৪ ফাল্গুন ১৪৩২ বঙ্গাব্দ"
// From a specific Gregorian date
const d = new BanglaDate(new Date("2025-04-14"), "en");
console.log(d.format("DD MMMM YYYY era")); // "01 Boishakh 1432 BA"
console.log(d.getOrdinalDate()); // "1st"
// Arithmetic
const next = d.add(30, "days");
console.log(next.toString()); // "01 Jyoishtho 1432 BA"
// Parse from Bangla date string
const parsed = BanglaDate.parse("1 Boishakh 1432");
console.log(parsed.toGregorian().toISOString()); // "2025-04-14T00:00:00.000Z"Language Support
| Code | Language | Digits | Example output |
| ---- | -------- | ------ | ---------------------------- |
| en | English | 0–9 | "24 Falgun 1432 BA" |
| bn | Bengali | ০–৯ | "২৪ ফাল্গুন ১৪৩২ বঙ্গাব্দ" |
| hi | Hindi | ०–९ | "२४ फाल्गुन १४३२ बंगाब्द" |
The language parameter is accepted by the constructor and by every static factory method. All text-returning instance methods (month names, weekday names, era, season, ordinal, relative time, etc.) respect the language set at construction time.
API Reference
Constructor
new BanglaDate(gregorianDate: Date, language?: 'en' | 'bn' | 'hi'): BanglaDateCreates a BanglaDate from a standard JavaScript Date object.
| Parameter | Type | Default | Description |
| --------------- | ---------------------- | ------- | --------------------------------------------------- |
| gregorianDate | Date | — | Any valid JS Date. Time components are preserved. |
| language | 'en' \| 'bn' \| 'hi' | 'en' | Output language for all text-returning methods. |
const d = new BanglaDate(new Date("2025-04-14T06:00:00Z"), "bn");
d.toString(); // "১ বৈশাখ ১৪৩২ বঙ্গাব্দ"Static Factory Methods
BanglaDate.now(language?)
BanglaDate.now(language?: 'en' | 'bn' | 'hi'): BanglaDateReturns a BanglaDate for the current moment with the full time-of-day preserved.
Use today() when you only need date semantics (midnight UTC).
| Parameter | Default |
| ---------- | ------- |
| language | 'en' |
BanglaDate.now("bn").toString(); // e.g. "২৪ ফাল্গুন ১৪৩২ বঙ্গাব্দ"BanglaDate.today(language?)
BanglaDate.today(language?: 'en' | 'bn' | 'hi'): BanglaDateReturns a BanglaDate set to midnight UTC of today. Equivalent to now() without time components.
| Parameter | Default |
| ---------- | ------- |
| language | 'en' |
BanglaDate.today("hi").format("DD MMMM YYYY era");
// "२४ फाल्गुन १४३२ बंगाब्द"BanglaDate.fromBanglaDate(year, month, day, language?)
BanglaDate.fromBanglaDate(
year: number,
month: number,
day: number,
language?: 'en' | 'bn' | 'hi'
): BanglaDateCreates a BanglaDate from explicit Bangla calendar components.
| Parameter | Type | Default | Description |
| ---------- | -------- | ------- | --------------------------------------------- |
| year | number | — | Bangla year (e.g. 1432) |
| month | number | — | 1-indexed month (1 = Boishakh … 12 = Chaitra) |
| day | number | — | Day of month |
| language | string | 'en' | Output language |
Throws BanglaDateRangeError if month or day is out of range.
BanglaDate.fromBanglaDate(1432, 1, 1, "en").toString();
// "1 Boishakh 1432 BA"BanglaDate.parse(dateString, language?)
BanglaDate.parse(dateString: string, language?: 'en' | 'bn' | 'hi'): BanglaDateParses a Bangla date string in the format "DD MonthName YYYY" (English month names only).
| Parameter | Type | Default | Description |
| ------------ | -------- | ------- | ---------------------------------------------------------- |
| dateString | string | — | e.g. "15 Boishakh 1432". Month name is case-insensitive. |
| language | string | 'en' | Language for the returned instance. |
Throws BanglaDateParseError on malformed input, BanglaDateRangeError if the day is out of range.
BanglaDate.parse("15 Boishakh 1432", "bn").toString();
// "১৫ বৈশাখ ১৪৩২ বঙ্গাব্দ"Valid month names: Boishakh, Jyoishtho, Asharh, Shrabon, Bhadro, Ashwin, Kartik, Ogrohayon, Poush, Magh, Falgun, Chaitra.
BanglaDate.isLeapYear(year)
BanglaDate.isLeapYear(year: number): booleanReturns true when the given Gregorian year is a leap year using the standard proleptic rule (÷4 except centuries unless ÷400).
Pass the Gregorian year, not the Bangla year.
BanglaDate.isLeapYear(2024); // true
BanglaDate.isLeapYear(1900); // false
BanglaDate.isLeapYear(2000); // trueBanglaDate.getMonthLengths(gregorianRefYear)
BanglaDate.getMonthLengths(gregorianRefYear: number): number[]Returns an array of 12 day-counts for the Bangla year whose Pohela Boishakh falls in gregorianRefYear.
Months 1–5 = 31 days, months 6–11 = 30 days, month 12 (Chaitra) = 30 or 31 days.
BanglaDate.getMonthLengths(2024);
// [31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 31] (2025 is leap → Chaitra = 31)BanglaDate.isValidBanglaDate(year, month, day)
BanglaDate.isValidBanglaDate(year: number, month: number, day: number): booleanReturns true when the given Bangla calendar components form a valid date.
BanglaDate.isValidBanglaDate(1432, 12, 31); // false (Chaitra max 30 in non-leap)
BanglaDate.isValidBanglaDate(1432, 1, 31); // trueValidity
isValid()
isValid(): booleanReturns true if this instance represents a valid date (underlying Date is not NaN, month index is 0–11, day is within the allowed range).
Comparison Methods
isBefore(other)
isBefore(other: BanglaDate): booleanReturns true when this date is strictly before other (compares millisecond timestamps).
isAfter(other)
isAfter(other: BanglaDate): booleanReturns true when this date is strictly after other.
isSame(other, granularity?)
isSame(other: BanglaDate, granularity?: 'day' | 'month' | 'year'): booleanReturns true when both dates match at the given granularity.
| Parameter | Type | Default | Description |
| ------------- | ---------------------------- | ------- | ------------------------ |
| other | BanglaDate | — | Date to compare against |
| granularity | 'day' \| 'month' \| 'year' | 'day' | How precisely to compare |
const a = BanglaDate.fromBanglaDate(1432, 1, 10);
const b = BanglaDate.fromBanglaDate(1432, 1, 20);
a.isSame(b, "year"); // true
a.isSame(b, "month"); // true
a.isSame(b, "day"); // falseArithmetic Methods
add(amount, unit?)
add(amount: number, unit?: 'days' | 'months' | 'years'): BanglaDateReturns a new BanglaDate shifted forward by amount of the given unit. Negative values shift into the past. This instance is not mutated.
| Parameter | Type | Default | Description |
| --------- | ------------------------------- | -------- | -------------------------------- |
| amount | number | — | Units to shift (can be negative) |
| unit | 'days' \| 'months' \| 'years' | 'days' | Unit of addition |
When adding months or years, if the resulting month is shorter than the current day, the day is clamped to the last valid day of the new month.
const d = BanglaDate.fromBanglaDate(1432, 1, 31);
d.add(1, "months").toString(); // "31 Jyoishtho 1432 BA"
d.add(-1, "years").toString(); // "31 Boishakh 1431 BA"
d.add(3, "days").toString(); // "4 Jyoishtho 1432 BA"subtract(amount, unit?)
subtract(amount: number, unit?: 'days' | 'months' | 'years'): BanglaDateConvenience wrapper around add(-amount, unit). Identical parameters and return type.
BanglaDate.today().subtract(7, "days"); // one week agodiff(other, unit?)
diff(other: BanglaDate, unit?: 'days' | 'months' | 'years'): numberReturns the signed difference between this date and other. A positive result means this date is after other.
| Parameter | Type | Default |
| --------- | ------------------------------- | -------- |
| other | BanglaDate | — |
| unit | 'days' \| 'months' \| 'years' | 'days' |
const start = BanglaDate.fromBanglaDate(1432, 1, 1);
const end = BanglaDate.fromBanglaDate(1432, 3, 15);
end.diff(start, "days"); // 76
end.diff(start, "months"); // 2
end.diff(start, "years"); // 0Start / End Helpers
| Method | Returns |
| ---------------- | ---------------------------------------------- |
| startOfMonth() | New BanglaDate at day 1 of this month |
| endOfMonth() | New BanglaDate at the last day of this month |
| startOfYear() | New BanglaDate at 1 Boishakh of this year |
| endOfYear() | New BanglaDate at the last day of Chaitra |
All methods return a new instance; the original is not modified.
const d = BanglaDate.fromBanglaDate(1432, 6, 15);
d.startOfMonth().toString(); // "1 Ashwin 1432 BA"
d.endOfMonth().toString(); // "30 Ashwin 1432 BA"
d.startOfYear().toString(); // "1 Boishakh 1432 BA"
d.endOfYear().toString(); // "30 Chaitra 1432 BA"Calendar Info
getDayOfYear()
getDayOfYear(): numberReturns the 1-based day number within the Bangla year (1–365 in a common year, 1–366 in a leap year).
BanglaDate.fromBanglaDate(1432, 1, 1).getDayOfYear(); // 1
BanglaDate.fromBanglaDate(1432, 2, 1).getDayOfYear(); // 32getRitu()
getRitu(): stringReturns the Bengali season (Ritu) for the current month, in the instance's language.
| Months | en | bn | hi | | ------------------ | -------- | ------- | ------- | | Boishakh–Jyoishtho | Grishmo | গ্রীষ্ম | ग्रीष्म | | Asharh–Shrabon | Borsha | বর্ষা | वर्षा | | Bhadro–Ashwin | Shorot | শরৎ | शरद | | Kartik–Ogrohayon | Hemonto | হেমন্ত | हेमन्त | | Poush–Magh | Sheet | শীত | शीत | | Falgun–Chaitra | Boshonto | বসন্ত | वसन्त |
getEra()
getEra(): stringReturns the era label: "BA" (English), "বঙ্গাব্দ" (Bengali), "बंगाब्द" (Hindi).
getFestival()
getFestival(): stringReturns the name of a major Bengali festival on this date, or an empty string if none.
| Date | en | bn | | ------------------- | ---------------------------------- | -------------------- | | 1 Boishakh | Pohela Boishakh (Bengali New Year) | পহেলা বৈশাখ (নববর্ষ) | | 25 Boishakh | Rabindra Jayanti | রবীন্দ্র জয়ন্তী | | 11 Jyoishtho | Nazrul Jayanti | নজরুল জয়ন্তী | | Last day of Chaitra | Chaitra Sangkranti (Year end) | চৈত্র সংক্রান্তি |
relativeTime()
relativeTime(): stringReturns a human-readable relative time string comparing this date to today.
// Assuming today is 24 Falgun 1432
BanglaDate.fromBanglaDate(1432, 2, 24).relativeTime(); // "in 1 month"
BanglaDate.fromBanglaDate(1431, 1, 1).relativeTime(); // "in 2 years" (if future)
BanglaDate.today("bn").relativeTime(); // "আজ"getOrdinalDate()
getOrdinalDate(): stringReturns the ordinal form of the day of the month in the instance's language.
| Language | Day 1 | Day 2 | Day 5 | Day 21 |
| -------- | ------- | ------- | ------ | ------- |
| en | 1st | 2nd | 5th | 21st |
| bn | পহেলা | দোসরা | ৫ই | ২১শে |
| hi | पहला | दूसरा | ५वाँ | २१वें |
Accessor Methods
All accessor methods return raw numbers (not localised strings). Use numberToNumber(value, language) from the utilities export when you need localised digit strings in custom code.
| Method | Returns | Description |
| ---------------------- | -------- | ------------------------------------------------------- |
| getDate() | number | Day of the Bangla month (1–31) |
| getDay() | number | UTC weekday index (0 = Sunday … 6 = Saturday) |
| getFullYear() | number | Full 4-digit Bangla year (e.g. 1432) |
| getYear() | number | Alias of getFullYear() |
| getMonth() | number | 1-indexed Bangla month (1 = Boishakh … 12 = Chaitra) |
| getHours() | number | UTC hour (0–23) |
| getMinutes() | number | UTC minutes (0–59) |
| getSeconds() | number | UTC seconds (0–59) |
| getMilliseconds() | number | UTC milliseconds (0–999) |
| getTime() | number | Unix timestamp in milliseconds |
| getTimezoneOffset() | number | Host timezone offset in minutes (positive = behind UTC) |
| getUTCDate() | number | Gregorian UTC day-of-month |
| getUTCDay() | number | Gregorian UTC weekday index (0 = Sunday) |
| getUTCFullYear() | number | Gregorian UTC 4-digit year |
| getUTCHours() | number | UTC hour of the underlying Gregorian timestamp |
| getUTCMinutes() | number | UTC minutes of the underlying Gregorian timestamp |
| getUTCSeconds() | number | UTC seconds of the underlying Gregorian timestamp |
| getUTCMilliseconds() | number | UTC milliseconds of the underlying Gregorian timestamp |
| getUTCMonth() | number | Gregorian UTC month index 0-based (not Bangla) |
Formatting Methods
toString()
Full localised date string: "15 Boishakh 1432 BA" / "১৫ বৈশাখ ১৪৩২ বঙ্গাব্দ" / "१५ बैशाख १४३२ बंगाब्द".
toDateString()
Short date + weekday string, e.g. "Monday, 15 Boishakh 1432".
toISOString()
ISO 8601-like string using Bangla calendar coordinates: "1432-01-15T08:26:34.809Z".
toTimeString()
Localised UTC time string, e.g. "08:26:34 UTC" / "০৮:২৬:৩৪ UTC".
toLocaleDateString(locales?, options?)
toLocaleDateString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): stringLocalised date-only string powered by Intl.DateTimeFormat. Bangla calendar fields replace the Gregorian ones. The timeZone option must be "UTC" or omitted.
| Parameter | Default | Description |
| --------- | --------------------------------- | --------------------------------------- |
| locales | Instance language | BCP 47 locale ("en-US", "bn-BD", …) |
| options | { year, month, day: 'numeric' } | Intl.DateTimeFormatOptions |
const d = new BanglaDate(new Date("2025-04-14"), "en");
d.toLocaleDateString("en-US"); // "4/14/1432"
d.toLocaleDateString("bn-BD", { month: "long" }); // "১৪ বৈশাখ ১৪৩২"
d.toLocaleDateString("hi-IN", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
}); // "सोमवार, बैशाख 14, 1432"toLocaleString(locales?, options?)
Same as toLocaleDateString but defaults to including time components (year, month, day, hour, minute, second).
d.toLocaleString("bn-BD"); // "১৪/৪/১৪৩২, ৬:০০:০০ AM"toLocaleTimeString(locales?, options?)
Localised time-only string, e.g. "6:00:00 AM" / "৬:০০:০০ AM".
format(formatString)
format(formatString: string): stringFormats the date using a token-based format string. All digits are automatically localised to the instance's language. Wrap literal text in [...] to prevent parsing as tokens.
See Format Tokens for the full token list.
const d = BanglaDate.fromBanglaDate(1432, 1, 5, "bn");
d.format("DD MMMM YYYY era"); // "০৫ বৈশাখ ১৪৩২ বঙ্গাব্দ"
d.format("WWWW, Do MMMM YYYY"); // "সোমবার, পহেলা বৈশাখ ১৪৩২"
d.format("[আজকের তারিখ:] DD/MM/YYYY"); // "আজকের তারিখ: ০৫/০১/১৪৩২"
d.format("HH:mm:ss AM/PM"); // "০৬:০০:০০ AM"Utility / Conversion
toGregorian()
Returns a defensive copy of the underlying Gregorian Date object.
d.toGregorian() instanceof Date; // truetoJSON()
Returns a plain object for JSON.stringify:
{
year: 1432,
month: 1,
day: 5,
era: 'BA',
hours: 0,
minutes: 0,
seconds: 0,
milliseconds: 0
}clone()
Returns a new independent BanglaDate identical to this one (deep copy, same language).
[Symbol.toPrimitive]
Allows use in numeric and string contexts:
+BanglaDate.today(); // Unix timestamp in ms (e.g. 1744329600000)
`${BanglaDate.today("bn")}`; // "২৪ ফাল্গুন ১৪৩২ বঙ্গাব্দ"Error Types
All errors extend BanglaDateError which itself extends Error.
| Class | Extends | When thrown |
| ---------------------- | ----------------- | ---------------------------------------------------------------------------- |
| BanglaDateError | Error | Base class — never thrown directly. |
| BanglaDateRangeError | BanglaDateError | A numeric argument (year, month, day) is outside its valid range. |
| BanglaDateParseError | BanglaDateError | A date string passed to parse() is malformed or has an unknown month name. |
import {
BanglaDate,
BanglaDateParseError,
BanglaDateRangeError,
} from "@subrotosaha/bangla-date";
try {
BanglaDate.parse("bad input");
} catch (e) {
if (e instanceof BanglaDateParseError) {
console.error("Parse error:", e.message);
}
}
try {
BanglaDate.fromBanglaDate(1432, 13, 1); // month 13 does not exist
} catch (e) {
if (e instanceof BanglaDateRangeError) {
console.error("Range error:", e.message);
}
}Format Tokens
Used with the format(formatString) method. All numeric output is automatically localised to the instance's language (en / bn / hi).
| Token | en example | bn example | Description |
| ------- | ----------- | ----------- | ------------------------------------------------------------ |
| YYYY | 1432 | ১৪৩২ | 4-digit Bangla year |
| YY | 32 | ৩২ | 2-digit Bangla year |
| MMMM | Boishakh | বৈশাখ | Full month name |
| MMM | Boi | বৈশা | Short month name |
| MM | 01 | ০১ | Zero-padded month number (01–12) |
| M | 1 | ১ | Month number without padding (1–12) |
| DD | 05 | ০৫ | Zero-padded day of month (01–31) |
| D | 5 | ৫ | Day of month without padding (1–31) |
| Do | 5th | পহেলা | Ordinal day of month (language-aware) |
| 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 | AM / PM | Day period uppercase |
| era | BA | বঙ্গাব্দ | Era label in the instance's language |
| [...] | (literal) | (literal) | Escaped section — not parsed as tokens, digits not localised |
Escape example
d.format("[Day:] DD [of] MMMM, YYYY");
// English: "Day: 05 of Boishakh, 1432"
// Bengali: "Day: ০৫ of বৈশাখ, ১৪৩২"Note:
WWis the weekday index (zero-padded), not an ISO week number.
Changelog
See CHANGELOG.md for release history.
License
ISC © subrotosaha
