UNPKG

bangla-date-utils

Version:

A utility package for converting and formatting dates in the Bangla calendar system with support for Bangla numerals.

409 lines (385 loc) 12.2 kB
// Constants for Bangla calendar export const BANGLA_MONTHS = [ "বৈশাখ", // Boishakh "জ্যৈষ্ঠ", // Jyoishtho "আষাঢ়", // Asharh "শ্রাবণ", // Shrabon "ভাদ্র", // Bhadro "আশ্বিন", // Ashwin "কার্তিক", // Kartik "অগ্রহায়ণ", // Ogrohayon "পৌষ", // Poush "মাঘ", // Magh "ফাল্গুন", // Falgun "চৈত্র", // Choitro ] export const BANGLA_SEASONS = [ "গ্রীষ্ম", // Grishmo (Summer) "বর্ষা", // Borsha (Rainy) "শরৎ", // Shorot (Autumn) "হেমন্ত", // Hemonto (Late Autumn) "শীত", // Sheet (Winter) "বসন্ত", // Boshonto (Spring) ] export const BANGLA_WEEKDAYS = [ "রবিবার", // Sunday "সোমবার", // Monday "মঙ্গলবার", // Tuesday "বুধবার", // Wednesday "বৃহস্পতিবার", // Thursday "শুক্রবার", // Friday "শনিবার", // Saturday ] // Bangla date structure export interface BanglaDate { year: number month: number // 1-12 date: number // 1-31 monthName: string season: string } /** * Determines if the given Bangla year is a leap year * @param year Bangla year * @returns boolean indicating if it's a leap year */ export const isBanglaLeapYear = (year: number): boolean => { // Convert Bangla year to Gregorian year (approximate) const gregorianYear = year - 593 // Gregorian leap year calculation return (gregorianYear % 4 === 0 && gregorianYear % 100 !== 0) || gregorianYear % 400 === 0 } /** * Get the number of days in a Bangla month * @param month Bangla month (1-12) * @param year Bangla year * @returns number of days in the month */ export const getDaysInBanglaMonth = (month: number, year: number): number => { // Bangla months have either 30 or 31 days // Falgun (11th month) has 29 days in non-leap years and 30 days in leap years if (month === 11) { return isBanglaLeapYear(year) ? 30 : 29 } // Chaitra (12th month) has 30 days if (month === 12) { return 30 } // Other months alternate between 31 and 30 days return month % 2 === 1 ? 31 : 30 } /** * Convert Gregorian date to Bangla date * @param date Gregorian date * @returns BanglaDate object */ export const convertGregorianToBangla = (date: Date): BanglaDate => { const gregorianDate = date.getDate() const gregorianMonth = date.getMonth() + 1 // 1-12 const gregorianYear = date.getFullYear() let banglaDate: number let banglaMonth: number let banglaYear: number // Bangla new year starts around April 14 // This is a simplified calculation - a more accurate one would account for leap years if (gregorianMonth < 4 || (gregorianMonth === 4 && gregorianDate < 14)) { // Jan to mid-April: Bangla year is Gregorian year - 594 banglaYear = gregorianYear - 594 } else { // Mid-April to Dec: Bangla year is Gregorian year - 593 banglaYear = gregorianYear - 593 } // Approximate mapping of Gregorian to Bangla dates // This is a simplified version - a more accurate version would use astronomical calculations if (gregorianMonth === 4) { // April if (gregorianDate < 14) { banglaMonth = 12 // Chaitra banglaDate = gregorianDate + 17 } else { banglaMonth = 1 // Boishakh banglaDate = gregorianDate - 13 } } else if (gregorianMonth === 5) { // May if (gregorianDate < 15) { banglaMonth = 1 // Boishakh banglaDate = gregorianDate + 17 } else { banglaMonth = 2 // Jyoishtho banglaDate = gregorianDate - 14 } } else if (gregorianMonth === 6) { // June if (gregorianDate < 15) { banglaMonth = 2 // Jyoishtho banglaDate = gregorianDate + 17 } else { banglaMonth = 3 // Asharh banglaDate = gregorianDate - 14 } } else if (gregorianMonth === 7) { // July if (gregorianDate < 16) { banglaMonth = 3 // Asharh banglaDate = gregorianDate + 16 } else { banglaMonth = 4 // Shrabon banglaDate = gregorianDate - 15 } } else if (gregorianMonth === 8) { // August if (gregorianDate < 16) { banglaMonth = 4 // Shrabon banglaDate = gregorianDate + 16 } else { banglaMonth = 5 // Bhadro banglaDate = gregorianDate - 15 } } else if (gregorianMonth === 9) { // September if (gregorianDate < 16) { banglaMonth = 5 // Bhadro banglaDate = gregorianDate + 16 } else { banglaMonth = 6 // Ashwin banglaDate = gregorianDate - 15 } } else if (gregorianMonth === 10) { // October if (gregorianDate < 16) { banglaMonth = 6 // Ashwin banglaDate = gregorianDate + 15 } else { banglaMonth = 7 // Kartik banglaDate = gregorianDate - 15 } } else if (gregorianMonth === 11) { // November if (gregorianDate < 15) { banglaMonth = 7 // Kartik banglaDate = gregorianDate + 16 } else { banglaMonth = 8 // Ogrohayon banglaDate = gregorianDate - 14 } } else if (gregorianMonth === 12) { // December if (gregorianDate < 15) { banglaMonth = 8 // Ogrohayon banglaDate = gregorianDate + 16 } else { banglaMonth = 9 // Poush banglaDate = gregorianDate - 14 } } else if (gregorianMonth === 1) { // January if (gregorianDate < 14) { banglaMonth = 9 // Poush banglaDate = gregorianDate + 17 } else { banglaMonth = 10 // Magh banglaDate = gregorianDate - 13 } } else if (gregorianMonth === 2) { // February if (gregorianDate < 13) { banglaMonth = 10 // Magh banglaDate = gregorianDate + 18 } else { banglaMonth = 11 // Falgun banglaDate = gregorianDate - 12 } } else { // March if (gregorianDate < 15) { banglaMonth = 11 // Falgun banglaDate = gregorianDate + 16 } else { banglaMonth = 12 // Chaitra banglaDate = gregorianDate - 14 } } // Get season based on Bangla month let seasonIndex = Math.floor((banglaMonth - 1) / 2) if (seasonIndex > 5) seasonIndex = 5 return { year: banglaYear, month: banglaMonth, date: banglaDate, monthName: BANGLA_MONTHS[banglaMonth - 1], season: BANGLA_SEASONS[seasonIndex], } } /** * Convert Bangla date to Gregorian date * @param banglaDate Bangla date (day) * @param banglaMonth Bangla month (1-12) * @param banglaYear Bangla year * @returns JavaScript Date object */ export const convertBanglaToGregorian = (banglaDate: number, banglaMonth: number, banglaYear: number): Date => { let gregorianYear = banglaYear + 593 let gregorianMonth = 0 // 0-11 for JavaScript Date let gregorianDate = 0 // Approximate mapping of Bangla to Gregorian dates // This is a simplified version - a more accurate version would use astronomical calculations if (banglaMonth === 1) { // Boishakh (mid-April to mid-May) if (banglaDate <= 18) { gregorianMonth = 3 // April gregorianDate = banglaDate + 13 } else { gregorianMonth = 4 // May gregorianDate = banglaDate - 18 } } else if (banglaMonth === 2) { // Jyoishtho (mid-May to mid-June) if (banglaDate <= 17) { gregorianMonth = 4 // May gregorianDate = banglaDate + 14 } else { gregorianMonth = 5 // June gregorianDate = banglaDate - 17 } } else if (banglaMonth === 3) { // Asharh (mid-June to mid-July) if (banglaDate <= 16) { gregorianMonth = 5 // June gregorianDate = banglaDate + 14 } else { gregorianMonth = 6 // July gregorianDate = banglaDate - 16 } } else if (banglaMonth === 4) { // Shrabon (mid-July to mid-August) if (banglaDate <= 16) { gregorianMonth = 6 // July gregorianDate = banglaDate + 15 } else { gregorianMonth = 7 // August gregorianDate = banglaDate - 16 } } else if (banglaMonth === 5) { // Bhadro (mid-August to mid-September) if (banglaDate <= 16) { gregorianMonth = 7 // August gregorianDate = banglaDate + 15 } else { gregorianMonth = 8 // September gregorianDate = banglaDate - 16 } } else if (banglaMonth === 6) { // Ashwin (mid-September to mid-October) if (banglaDate <= 15) { gregorianMonth = 8 // September gregorianDate = banglaDate + 15 } else { gregorianMonth = 9 // October gregorianDate = banglaDate - 15 } } else if (banglaMonth === 7) { // Kartik (mid-October to mid-November) if (banglaDate <= 16) { gregorianMonth = 9 // October gregorianDate = banglaDate + 15 } else { gregorianMonth = 10 // November gregorianDate = banglaDate - 16 } } else if (banglaMonth === 8) { // Ogrohayon (mid-November to mid-December) if (banglaDate <= 15) { gregorianMonth = 10 // November gregorianDate = banglaDate + 14 } else { gregorianMonth = 11 // December gregorianDate = banglaDate - 15 } } else if (banglaMonth === 9) { // Poush (mid-December to mid-January) if (banglaDate <= 16) { gregorianMonth = 11 // December gregorianDate = banglaDate + 14 } else { gregorianMonth = 0 // January gregorianDate = banglaDate - 16 gregorianYear += 1 } } else if (banglaMonth === 10) { // Magh (mid-January to mid-February) if (banglaDate <= 18) { gregorianMonth = 0 // January gregorianDate = banglaDate + 13 } else { gregorianMonth = 1 // February gregorianDate = banglaDate - 18 } } else if (banglaMonth === 11) { // Falgun (mid-February to mid-March) if (banglaDate <= 16) { gregorianMonth = 1 // February gregorianDate = banglaDate + 12 } else { gregorianMonth = 2 // March gregorianDate = banglaDate - 16 } } else { // Chaitra (mid-March to mid-April) if (banglaDate <= 17) { gregorianMonth = 2 // March gregorianDate = banglaDate + 14 } else { gregorianMonth = 3 // April gregorianDate = banglaDate - 17 } } return new Date(gregorianYear, gregorianMonth, gregorianDate) } /** * Get the Bangla weekday name for a given date * @param date JavaScript Date object * @returns Bangla weekday name */ export const getBanglaWeekday = (date: Date): string => { const dayIndex = date.getDay() // 0-6, where 0 is Sunday return BANGLA_WEEKDAYS[dayIndex] } /** * Get the current Bangla date * @returns BanglaDate object for the current date */ export const getCurrentBanglaDate = (): BanglaDate => { return convertGregorianToBangla(new Date()) } /** * Format a Bangla date as a string * @param banglaDate BanglaDate object * @param format Format string (e.g., 'full', 'medium', 'short') * @returns Formatted Bangla date string */ export const formatBanglaDateString = ( banglaDate: BanglaDate, format: "full" | "medium" | "short" = "medium", ): string => { const { date, month, year, monthName, season } = banglaDate // Convert numbers to Bangla numerals const banglaNumerals = ["০", "১", "২", "৩", "৪", "৫", "৬", "৭", "৮", "৯"] const toBanglaNumerals = (num: number) => { return num .toString() .split("") .map((digit) => banglaNumerals[Number.parseInt(digit)]) .join("") } const banglaDateNum = toBanglaNumerals(date) const banglaYear = toBanglaNumerals(year) if (format === "full") { return `${banglaDateNum} ${monthName} ${banglaYear} (${season})` } else if (format === "short") { return `${banglaDateNum}/${toBanglaNumerals(month)}/${banglaYear}` } else { // medium format return `${banglaDateNum} ${monthName} ${banglaYear}` } }