Code · Python
Julian dates in Python
Two things share the name “Julian date”. This page shows both
in Python: the day-of-year ordinal codes (YYYYDDD, YYDDD) from
strftime, and the astronomical Julian Date (JD) and Modified
Julian Date (MJD) with a correct algorithm and an astropy
shortcut.
Two different “Julian dates”
The ordinal form is a year plus day-of-year
(1–365/366), like 2026202, common in manufacturing and
IT. The astronomical form is a continuous count of days
since noon on 1 January 4713 BC, like 2461242.5.
Prefer a browser tool? Use the
Julian date converter.
Day-of-year (ordinal) Julian dates
Everything here comes from the standard library.
from datetime import date, datetime The raw day of year (1–366) is available on the time tuple:
>>> date(2026, 7, 21).timetuple().tm_yday
202
For the padded string codes, use strftime. The
%j directive is the zero-padded three-digit day of year,
%Y the four-digit year and %y the two-digit year:
>>> datetime(2026, 7, 21).strftime('%Y%j') # 7-digit YYYYDDD
'2026202'
>>> datetime(2026, 7, 21).strftime('%y%j') # 5-digit YYDDD
'26202' Parsing a code back into a date uses the same directives with strptime:
>>> datetime.strptime('2026202', '%Y%j').date()
datetime.date(2026, 7, 21)
>>> datetime.strptime('26202', '%y%j').date()
datetime.date(2026, 7, 21) Two-digit years are ambiguous
%y follows Python’s convention: values 00–68 map
to 2000–2068 and 69–99 map to 1969–1999. If your data
spans a different range, parse the century yourself rather than trusting
%y.
Astronomical Julian Date (JD) and MJD
The datetime module has no built-in JD, so use the classic algorithm. It works for any calendar date and includes the fractional time of day:
def to_jd(dt):
"""Astronomical Julian Date for a datetime assumed to be UTC.
Valid across the Gregorian and Julian calendars (Fliegel/Meeus)."""
y, m = dt.year, dt.month
# fractional day, including the time of day
d = dt.day + (dt.hour + dt.minute / 60 + dt.second / 3600) / 24
if m <= 2:
y -= 1
m += 12
a = y // 100
b = 2 - a + a // 4
jd = int(365.25 * (y + 4716)) + int(30.6001 * (m + 1)) + d + b - 1524.5
return jd
def to_mjd(dt):
return to_jd(dt) - 2400000.5 >>> to_jd(datetime(2026, 7, 21, 0, 0, 0))
2461242.5
>>> to_jd(datetime(2026, 7, 21, 12, 0, 0))
2461243.0
>>> to_mjd(datetime(2026, 7, 21))
61242.0
Remember the JD day starts at noon, so midnight UTC lands
on a .5. The MJD (JD − 2400000.5) instead starts
at midnight and drops the leading millions.
Shortcut for date-only values
For a plain date at 00:00, toordinal() gives a proleptic
Gregorian day count where date(1, 1, 1) is 1. Add the JD of
that epoch to get the Julian Date:
>>> d = date(2026, 7, 21)
>>> d.toordinal() + 1721424.5 # JD at 00:00 UTC
2461242.5
# reverse, for the date-only case:
>>> date.fromordinal(round(2461242.5 - 1721424.5))
datetime.date(2026, 7, 21) Proleptic Gregorian
toordinal() extends the Gregorian calendar backwards, so for
dates before the 1582 reform it will differ from the Julian-calendar
to_jd result above. For modern dates the two agree exactly.
With astropy
For serious astronomy, let astropy handle time scales,
leap seconds and the reverse conversion:
from astropy.time import Time
>>> Time('2026-07-21 00:00:00', scale='utc').jd
2461242.5
>>> Time(2461242.5, format='jd', scale='utc').iso
'2026-07-21 00:00:00.000'
>>> Time(2461242.5, format='jd').mjd
61242.0
Lighter alternatives exist too: jdcal offers small
gcal2jd / jd2gcal helpers, and
Astropy.time.Time covers JD, MJD and dozens of other formats
in one object.
Worked example: 21 July 2026
import datetime as dt
d = dt.datetime(2026, 7, 21)
d.strftime('%Y%j') # -> '2026202' (ordinal, 7-digit)
d.strftime('%y%j') # -> '26202' (ordinal, 5-digit)
d.timetuple().tm_yday # -> 202 (day of year)
to_jd(d) # -> 2461242.5 (astronomical JD)
to_jd(d) - 2400000.5 # -> 61242.0 (MJD) Next steps
Want the same conversions in the browser? See the JavaScript examples or the Julian day converter. Other languages: SQL and Excel.