UNPKG

bs-ad-converter

Version:

A library for converting between BS (Bikram Sambat) and AD (Anno Domini) dates.

132 lines 5.25 kB
// src/nepali-date.ts import { BS_DATA, DAYS_OF_WEEK, ENGLISH_MONTHS, NEPALI_DAYS, NEPALI_MONTHS, NEPALI_NUMBERS } from './bs-data.js'; /** Check if a Gregorian year is a leap year */ export const isLeapYear = (year) => (year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0); /** Get index of Nepali year in BS_DATA */ const getNepaliYearIndex = (yy) => yy - 2000; /** Validate English date */ const validateEngDate = (yy, mm, dd) => { if (yy < 1944 || yy > 2099) throw new Error('Supported English years are from 1944 to 2099'); if (mm < 1 || mm > 12) throw new Error('Month must be between 1-12'); if (dd < 1 || dd > 31) throw new Error('Day must be between 1-31'); }; /** Validate Nepali date */ const validateNepDate = (yy, mm, dd) => { if (yy < 2000 || yy > 2099) throw new Error('Supported Nepali years are from 2000 to 2099'); if (mm < 1 || mm > 12) throw new Error('Month must be between 1-12'); const daysInMonth = BS_DATA[getNepaliYearIndex(yy)]?.[mm] ?? 0; if (dd < 1 || dd > daysInMonth) throw new Error(`Day must be between 1-${daysInMonth} for ${yy}-${mm}`); }; /** Convert English date (yyyy-mm-dd) to Nepali (BS) date */ export const adToBS = (yy, mm, dd) => { validateEngDate(yy, mm, dd); const engMonthDays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; const engLeapMonthDays = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Reference: 1944-01-01 AD = 2000-09-17 BS, Saturday (5) const refEyy = 1944, refEmm = 1, refEdd = 1; const refNyy = 2000, refNmm = 9, refNdd = 17; const refDayOfWeek = 6; // Saturday (Sunday = 0, Saturday = 6) let totalEngDays = 0; for (let i = refEyy; i < yy; i++) { totalEngDays += isLeapYear(i) ? 366 : 365; } const daysInCurrentYearMonths = isLeapYear(yy) ? engLeapMonthDays : engMonthDays; for (let i = 1; i < mm; i++) { totalEngDays += daysInCurrentYearMonths[i]; } totalEngDays += dd - refEdd; let nepYear = refNyy, nepMonth = refNmm, nepDate = refNdd; let daysToAdd = totalEngDays; while (daysToAdd > 0) { let daysInCurrentNepMonth = BS_DATA[getNepaliYearIndex(nepYear)]?.[nepMonth] ?? 0; let daysRemainingInMonth = daysInCurrentNepMonth - nepDate + 1; if (daysToAdd >= daysRemainingInMonth) { daysToAdd -= daysRemainingInMonth; nepMonth++; nepDate = 1; if (nepMonth > 12) { nepYear++; nepMonth = 1; } } else { nepDate += daysToAdd; daysToAdd = 0; } } const dayOfWeek = (refDayOfWeek + totalEngDays) % 7; return { year: nepYear, month: nepMonth, date: nepDate, day: NEPALI_DAYS[dayOfWeek], nmonth: NEPALI_MONTHS[nepMonth - 1], num_day: dayOfWeek + 1 }; }; //----------------------------------------------------------------------------------------------------------------------------------------------------------------- /** Convert Nepali date (yyyy-mm-dd) to English (AD) date */ export const bsToAD = (yy, mm, dd) => { validateNepDate(yy, mm, dd); const engMonthDays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; const engLeapMonthDays = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Reference: 1944-01-01 AD = 2000-09-17 BS, Saturday (5) const refEyy = 1944, refEmm = 1, refEdd = 1; const refNyy = 2000, refNmm = 9, refNdd = 17; const refDayOfWeek = 6; // Saturday (Sunday = 0, Saturday = 6) let totalNepDays = 0; for (let i = refNyy; i < yy; i++) { const yearData = BS_DATA[getNepaliYearIndex(i)]; for (let j = 1; j <= 12; j++) { totalNepDays += yearData?.[j] ?? 0; } } for (let j = 1; j < mm; j++) { totalNepDays += BS_DATA[getNepaliYearIndex(yy)]?.[j] ?? 0; } totalNepDays += dd - refNdd; let engYear = refEyy, engMonth = refEmm, engDate = refEdd; let daysToAdd = totalNepDays; while (daysToAdd > 0) { const daysInCurrentEngMonth = isLeapYear(engYear) ? engLeapMonthDays[engMonth] : engMonthDays[engMonth]; const daysRemainingInMonth = daysInCurrentEngMonth - engDate + 1; if (daysToAdd >= daysRemainingInMonth) { daysToAdd -= daysRemainingInMonth; engMonth++; engDate = 1; if (engMonth > 12) { engYear++; engMonth = 1; } } else { engDate += daysToAdd; daysToAdd = 0; } } const dayOfWeek = (refDayOfWeek + totalNepDays) % 7; return { year: engYear, month: engMonth, date: engDate, day: DAYS_OF_WEEK[dayOfWeek], emonth: ENGLISH_MONTHS[engMonth - 1], num_day: dayOfWeek + 1 }; }; /** Convert number to Nepali numerals */ export const convertToNepaliNumber = (str) => { return String(str).split('').map(ch => { const digit = parseInt(ch, 10); return isNaN(digit) ? ch : NEPALI_NUMBERS[digit]; }).join(''); }; console.log(adToBS(1998, 10, 24)); console.log(bsToAD(2055, 7, 7)); //# sourceMappingURL=test.js.map