Timeyard

Calendars تقویم‌ها

Convert Jalali to Gregorian in code (JS & Python)

On this pageدر این صفحه

If you’re building anything that touches Iranian dates, you’ll eventually need to convert Jalali to Gregorian in code. The good news: you should not write the algorithm yourself. The arithmetic is subtle, and well-tested libraries already handle it.

To sanity-check any single date against a reference, use the live converter (it runs the jalaali-js cycle):

JavaScript

jalaali-js is the de-facto standard and is what this site’s converter uses under the hood (source: jalaali-js on GitHub). The core call converts a Jalali year/month/day to Gregorian:

import { toGregorian } from 'jalaali-js'

// 1 Farvardin 1404 -> Gregorian
const g = toGregorian(1404, 1, 1)
// { gy: 2025, gm: 3, gd: 21 }

And back the other way with toJalaali(gy, gm, gd). The library works on plain year/month/day numbers, which is deliberate: it keeps you away from Date objects and their timezone behaviour for the conversion itself.

Python

In Python, jdatetime mirrors the standard datetime API, so it’s familiar:

import jdatetime

# Jalali date -> Gregorian
g = jdatetime.date(1404, 1, 1).togregorian()
# datetime.date(2025, 3, 21)

It also parses and formats Jalali dates, which is handy for I/O.

The edge cases you must test

Why you need a library (and shouldn’t hand-roll it)

These libraries exist instead of a one-line formula because the Persian leap rule is a 33-year cycle, not a modulo-4 check, so a naive conversion drifts. For example, assuming “every 4th year is leap” places 30 Esfand in the wrong year within a single cycle. Whichever language you use, the bugs cluster in the same places. Write tests for these:

The timezone trap

The most common production bug isn’t the calendar math at all, it’s mixing in timestamps. If you convert a Date/datetime that carries a time and zone, a value near midnight can land on the wrong calendar day. Convert on date-only values (year, month, day) and keep time zones out of the conversion path. This site’s converter is built date-only for exactly that reason; you can read more in days between dates, which hits the same issue.

Frequently asked questions

  • How do I convert Jalali to Gregorian in JavaScript?

    Use the jalaali-js library: toGregorian(jy, jm, jd) returns the Gregorian year, month, and day. Convert back with toJalaali(gy, gm, gd).

  • What library converts Jalali dates in Python?

    jdatetime mirrors Python’s datetime API: jdatetime.date(y, m, d).togregorian() returns a standard date. It also parses and formats Jalali dates.

  • Should I write the conversion algorithm myself?

    No. The 33-year leap cycle and month lengths are easy to get subtly wrong. Use a maintained library and test the boundaries.

  • What is the most common bug?

    Timezone leakage: converting a timestamp instead of a date-only value, which can shift the result by a day near midnight. Convert on year/month/day only.

In short: pick jalaali-js or jdatetime, convert on date-only values, and test the Nowruz and 30 Esfand boundaries. To verify a result by hand, the converter is your reference.

Open the converter بازگشت به مبدّل