With the magic of programming, you too can conveniently change between Gregorian and Nepali dates. Here I will show you exactly that using javascript.
On this page
The Nepali calendar (Bikram Sambat) is the official calendar of Nepal. It is a lunisolar calendar which may sound interesting but this causes a few headaches to the people as it is not as simple and consistent as it's Gregorian counterpart. Also having to constantly convert from Bikram Sambat(BS) to Gregorian(AD) is a huge challenge.
How is the Nepali calendar structured?
The Bikram Sambat has twelve months and a new year usually begins around 12–15 April. The start of a Nepali month lies approximately mid-way Gregorgian months.

Bikram Sambat Months | Gregorgian Months |
---|---|
Baisakh | April–May |
Jestha | May–June |
Ashad | June–July |
Shrawan | July–August |
Bhadra | August–September |
Ashoj | September–October |
Kartik | October–November |
Mangsir | November–December |
Poush | December–January |
Magh | January–February |
Falgun | February–March |
Chaitra | March–April |
Few quirks of the Nepali Calendar
-
Uncertain days in month. Since days in month are based on lunar phases but the year is based on earths position relative to earth, this can create conflicts and days in months are changed to compensate. Lets look at two consective years 2079 BS and 2080 BS.
Months 2079 2080 Baisakh 31 31 Jestha 31 32 Ashad 32 31 Shrawan 31 32 Bhadra 31 31 Ashoj 31 30 Kartik 30 30 Mangsir 29 30 Poush 30 29 Magh 29 29 Falgun 30 30 Chaitra 30 30 -
Leap years. Leap years may not be spaced every four years. In fact, on extremely rare occasions, there might be 364 days in a year. Taking a look at the next 10 consecutive years 2079 BS–2089 BS.
Year (BS) Days 2079 365 2080 365 2081 366 2082 365 2083 365 2084 365 2085 366 2086 365 2087 366 2088 365 2089 365 -
No fixed relation between dates. There seems to be no exact relation between Gregorian and Nepali calendar. A date this year might not lie on the same day next year. Look at these date when the Nepali New year lies.
Bikram Sambat (New Year) Gregorgian 01-01-2077 2020-04-13 01-01-2078 2021-04-14 01-01-2079 2022-04-14 01-01-2080 2023-04-14
Tackling the problem
- Find the Nepali year that the input Gregorian date lies on.
- A reference date is needed, usually it is taken as a single point in time or multiple references — say, start of every Nepali year.
- Find the total days passed respective to the selected reference date.
- For the month, keep adding up days in the month chronologically until it almost exceeds the days passed.
- For the day of month, the difference of the total days of month from before and days passed.
Setting up
Considering all the uncertainties it’s necessary to hard-code the start of each Nepali year. We’ll use this as reference date for finding the Nepali year and days passed.
const yearStart = {
'2078': '2021-04-14',
'2079': '2022-04-14',
'2080': '2023-04-14',
'2081': '2024-04-13',
'2082': '2025-04-14' // End of the previous year
};
We will also need to input length of each month of every year.
const monthLengths = {
'2078': [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
'2079': [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
'2080': [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
'2081': [31, 31, 32, 32, 31, 30, 30, 30, 29, 30, 30, 30]
};
Lets add labels for months which will be useful later.
const monthTitles = ['Baisakh',
'Jestha',
'Ashad',
'Shrawan',
'Bhadra',
'Ashoj',
'Kartik',
'Mangsir',
'Poush',
'Magh',
'Falgun',
'Chaitra'];
Step 1: Finding the year
Finding the Nepali year is straightforward, just loop though the array of reference dates and find the year where given date just exceeds the new year date.
// Convert any given date to timezone specific
function localiseDate(date) {
let options = {
timeZone: 'Asia/Kathmandu',
year: 'numeric',
month: 'numeric',
day: 'numeric',
}
let localDate = date.toLocaleString('en-GB', options);
// dd/mm/yyyy -> yyyy-mm-dd
localDate = localDate.split('/').reverse().join('-');
return localDate;
}
function getYear(date) {
// For the sake of accuracy with the reference
let localDate = localiseDate(date);
let npYear = null;
let lowerLimit = yearStart[Object.keys(yearStart)[0]];
// Finds the index(key) of the array where the condition satisfies
for (let key in yearStart) {
if (localDate >= lowerLimit &&
localDate < yearStart[key]) {
npYear = `${key - 1}`;
return npYear
}
}
return "error";
}
Step 2: Calculating total days passed
Total days passed is taken from the start of the Nepali year to the given date.
Note: daysPassed
needs to be incremented by 1
as it is calculated after first day of the reference year not from it.
function getDaysPassed(year, date) {
let localDate = localiseDate(date)
let givenDate = new Date(localDate);
let startDate = new Date(yearStart[year]);
// Difference of time in milliseconds then to days
let daysPassed = (givenDate.getTime() - startDate.getTime())/(1000*60*60*24);
return Math.round(daysPassed + 1);
}
Step 3: Finding the month and day of month
Subtract consecutive days in a month from days passed while also tracking the index for the month as monthIndex
. Then the remainder days is the dayOfMonth
(Date).
Visually,

function getMonthAndDate(year, date) {
let daysPassed = getDaysPassed(year, date);
let monthIndex = null;
let dayOfMonth = null;
for (let i = 0; i < 12; i++) {
if (daysPassed <= monthLengths[year][i]) {
monthIndex = i;
dayOfMonth = daysPassed;
break;
}
daysPassed -= monthLengths[year][i];
}
let result = {
'month': parseInt(monthIndex + 1),
'dayOfMonth': dayOfMonth
};
return result;
}
Step 4: Finishing up
Now we can calculate the any date from 2021-04-14 but before 2025-04-14.
let dateStr = "2022-12-02"; //yyyy-mm-dd
let date = new Date(dateStr);
let npYear = getYear(date);
if (npYear === "error") {
console.log("Error: Date is outside the limit!");
} else {
let npMonthAndDate = getMonthAndDate(npYear, date);
let npDate1 = `${npYear}-${npMonthAndDate['month']}-${npMonthAndDate['dayOfMonth']}`
console.log(npDate1);
// 2079-8-16
let npDate2 = `${monthTitles[npMonthAndDate['month'] - 1]} ${npMonthAndDate['dayOfMonth']}, ${npYear}`
console.log(npDate2);
// Mangsir 16, 2079
}
Conclusion
As you can see, conversion from BS to AD is fairly simple. This approach can be extended to include more range of dates.
For converting backwards, the same principle and data can be used with some minor changes to the code.
Resources
- Vikram Samvat (Bikram Sambat), Wikipedia
- English to Nepali Date Converter, Hamro Patro
Change log
- August 2, 2023
-
Fixed a bug with
localiseDate
function, where it would incorrectly format dates in different locales.function localiseDate(date) { … - let localDate = date.toLocaleString([], options); + let localDate = date.toLocaleString('en-GB', options); … }