date.toordinal / fromordinal

A date as one integer: consecutive days get consecutive numbers, so ordinals subtract, sort and store trivially. fromordinal (a class method, also usable on datetime) goes back.

date methodPython 2.3+Live demo
Common call
date(2026, 9, 29).toordinal()
Returns
739888
Replaces
Home-made day counts from an arbitrary epoch
Watch out
Not the astronomical Julian Day Number (that starts in 4713 BC)
d.toordinal()
→ int

Demo

Live evaluation
Date → ordinal, then ordinal + n → date.
Try:
Inputs
whenstrYYYY-MM-DD
nintdays to add to the ordinal
Code
from datetime import date
n = date.fromisoformat('2026-09-29').toordinal()
(n, date.fromordinal(n + 0))
Result
(739888, datetime.date(2026, 9, 29))

0001-01-01 is ordinal 1, so going one day earlier asks for ordinal 0: ValueError: ordinal must be >= 1.

Parameters

NameTypeRequiredDescription
ordinalintyesfromordinal only: 1 to 3652059 (date.max). Floats are rejected.

Return value

int — toordinal: day number, 1 for 0001-01-01. fromordinal(n): the date with that number.

Common patterns

Store dates as integers
Compact, sortable and exact.
day_number = d.toordinal()
d_again = date.fromordinal(day_number)
Days between dates without timedelta
Plain int subtraction.
gap = b.toordinal() - a.toordinal()

Examples

1. To an ordinal
from datetime import date date(2026, 9, 29).toordinal()
Returns
739888
2. And back
from datetime import date date.fromordinal(739888)
Returns
datetime.date(2026, 9, 29)
3. Day 1
from datetime import date date.fromordinal(1)
Returns
datetime.date(1, 1, 1)
4. On datetime: midnight
from datetime import datetime datetime.fromordinal(739888)
Returns
datetime.datetime(2026, 9, 29, 0, 0)
5. The time part is ignored
from datetime import datetime datetime(2026, 9, 29, 23, 59).toordinal()
Returns
739888
6. Out of range
from datetime import date date.fromordinal(3652060)
Returns
ValueError: year 10000 is out of range

Pitfalls

1. Passing a float ordinal
Ordinals are whole days; a float (from division, or a spreadsheet serial) is rejected. Convert explicitly.
float
from datetime import date
date.fromordinal(739888.0)
TypeError: 'float' object cannot be interpreted as an integer
int()
from datetime import date
date.fromordinal(int(739888.0))
datetime.date(2026, 9, 29)
2. Treating it as a Julian Day Number
Astronomical JDN counts from 4713 BC; Python ordinals from 1 AD. The offset is 1721424.5 days — do not mix them.
ordinal as JDN
from datetime import date
date(2026, 9, 29).toordinal()
739888
JDN at noon
from datetime import date
date(2026, 9, 29).toordinal() + 1721425
2461313

When to use

Use it
  • Compact integer storage of dates
  • Fast day arithmetic and bucketing
Reach for something else
  • Human-facing output → isoformat
  • Astronomy → a real JDN library

Notes

CPython impl
ymd_to_ord / ord_to_ymd in Modules/_datetimemodule.c, the same 400-year-cycle algorithm as Lib/_pydatetime.py
Range
1 (0001-01-01) to 3652059 (9999-12-31)
Inherited
datetime.fromordinal / datetime.toordinal are the same methods; the datetime result is at midnight

FAQ

The count of days in the Gregorian calendar extended backwards to year 1, with 0001-01-01 as day 1. date.toordinal() returns it and date.fromordinal() reverses it.