HOME | EO | FR | EN |

The original of this article is written in
esperanto, the fair international language,
in which *tagnumerilo* is composed of:

- final
*-o*= substantive (*-a*= adjective,*-e*= adverb,*-i*= infinitive) *tag*:*tago*= day,*taga*= dayly,*tage*= everyday*numer*:*numero*= number (n),*numeri*= number (v),*tagnumero*= day number*il*:*ilo*= tool,*numerilo*= numbering tool,*tagnumerilo*= day numbering tool

*If your internet browser forbids JavaScript,
you won't be able to see or use the following
JavaScript day numbering tool:*

- Contents:
- Why numbering days?
- Calendar facts
- Tableless integer arithmetic algorithm
- Inverse algorithm
- Uses of the Julian algorithm
- Codings
- Links

*How many days* are two calendar days apart?

- How many
*days*am I old? - Which
*weekday*was I born? - How many weeks was this period long?

*Which date* is that many days apart from this date?

- When was/am I
*10000 days old*? - When starts the grapes picking, 100 days after flowering?
- When comes our baby, 40 weeks after conception?

Such simple questions seem harder to answer, because the time counting systems,
i.e. *calendars*,
appear irregular, full of exceptions.
This is why calendar algorithms use tables for
computing every date's day number,
following a sequential numbering, after which the problem reduces
to a simple arithmetic difference between two day numbers.

This article presents a *tableless*
day numbering algorithm,
and its inverse (from day number to date), for the current occidental
Gregorian calendar, or its simpler Julian predecessor,
that can also be used nowdays if only through two centuries.
As both algorithms require only simple
integer arithmetics,
with only integer numbers and euclidian division
(i.e. with integer quotient and remainder), they are
very well suited for simple computing means,
such as hand computation, or the cheapest (and most used) microcontrollers.

The earth globe turns around its polar axis once a day vrt the sun, and around the sun once a year vrt far stars. The constant angle between these two axes causes the seasons, in synchrony with which try to be the so called "solar" calendars, such as the Gregorian and Julian ones. The present astronomical measure of one year is close to 365.2422 days.

The Julian calendar was initiated by the roman emperor Julius Caesar in 45 B.C. advised by egyptian astronoms. Its year is composed of 365 days, divided into the current 12 months, plus one "leap day", added on february the 29-th of every "leap year" multiple of four. This approximation of the year duration, meanly 365.25 day, excellent for the astronomical tools then available, however delays the Julian calendar by about 3 days every four centuries.

After sixteen centuries, the accumulated delay becoming too big, the Gregorian calendar was introduced by the catholic pope Gregor XIII in 1582. He first improved the approximation of the year duration, meanly 365.2425 days, by skipping the leap day of every year multiple of 100 but not of 400, i.e. of 3 leap days every four centuries, and moreover he resynchronized the calendar by skipping 10 days: the day following thursday 1582-10-04 was friday 1582-10-15.

The change, from the Julian calendar to the Gregorian, wasn't immediately adopted by all countries: first went the catholic ones (ex. France since monday 1582-12-20), then later the protestant (ex. England since thursday 1752-08-14), and even later the orthodox ones (ex. Russia since thursday 1918-02-14).

First, let's choose march 1st as starting point of the year period (and therefore let's number january=13 kaj february=14): to its end thus falls the occasional leap day. Moreover, a period of 5 months appears, of 31+30+31+30+31 = 153 days:

month (m): | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

number of days: | 31 | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 31 | 31 | 28 |

period: | 153 | 153 | ||||||||||

(((m+1)*153)/5)-122 | 0 | 31 | 61 | 92 | 122 | 153 | 184 | 214 | 245 | 275 | 306 | 337 |

A bit of attention, to the successive multiples of 153/5 and their differences, easily reveals the formula of the fourth table line, which equals the sum of the numbers of days of the months between march 1st and the 1st day of month "m"; add to it the monthday of the date to obtain the number of days between march 1st and that date.

Between march 1st of a given *base* leap year
(multiple of 400 for the Gregorian calendar, or of 4 for the Julian),
and march 1st of the "y"-th following year,
the number of days is
(y*365)+(y/4)-(y/100)+(y/400)
for the Gregorian calendar (or more simply
(y*365)+(y/4) for the Julian one).

Then, here is the day numbering algorithm, with Y=year M=month D=day, and NG or NJ = day number under the Gregorian or Julian calendar:

- choose a previous base leap year B (ex. B=2000 or B=1600 or even B=0)
- if M<3, compute y=B-Y-1 and m=M+12, otherwise y=B-Y and m=M
- NJ = (y*365)+(y/4) + (((m+1)*153)/5)-123 + D, or NG = NJ-(y/100)+(y/400)

In order to find the date weekday,
divide N into weekly periods of 7 days
(remarquably, the Gregorian four-century period of 146097 days is a
multiple of 7);
the remainder of the euclidian division equals:

remainder: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |

Julian (B=0): | mon | tue | wed | thu | fri | sat | sun |

Gregorian: | wed | thu | fri | sat | sun | mon | tue |

Example: 2005-09-03, Y=2005 M=9 D=3, y=5 m=9, NJ=NG=2012=7*287+3=saturday.

Firstly, divide the day number NG into four-century periods of 146097 days: NG=146097*Q+R (i.e. Q and R are the quotient and remainder of the euclidian division NG/146097). If R=146096, the date is the last leap day of the four-century period, february 29th of year Y=B+Q*400+400.

Otherwise, secondly divide R into century periods of 36524 days: R=36524*C+c. The previous two first steps are only adequate for the Gregorian calendar; for the Julian, start here with c=NJ.

Thirdly, divide c into four-year periods of 1461 days: c=1461*q+r. If r=1460, the date is a leap day, february 29th of year Y=B+Q*400+C*100+q*4+4.

Otherwise, fourthly divide r into year periods of 365 days: r=365*i+d, and compute y=B+Q*400+C*100+q*4+i, and m=(((d+31)*5)/153)+2, and D=d-(((m+1)*153)/5)+123.

Finally, if m>12, compute Y=y+1 and M=m-12, otherwise Y=y and M=m. The date is Y=year M=month D=day.

Example: NJ=2012, q=1 r=551, i=1 d=186, y=2005 m=9 D=3, Y=2005 M=9, 2005-09-03.

First, 16 to 19 centuries of history were dated under the Julian calendar. For example, during Zamenhof's life, russians were still using the Julian calendar (until its wednesday january 31st 1918, which was the Gregorian february 13rd), then 13 days late vrt the Gregorian, already in use by western countries for three centuries.

Second, microcontrollers compute less costly with 16 bits numbers, between 0 and 65535, i.e. the number of days of around 180 years. As between 1900-03-01 and 2100-02-28 the Gregorian and Julian leap years are identical, the simpler Julian algorithm may be used with for instance 1900 as base year (1900-03-01 = day number 0, until day number 65535 = 2079-05-05).

- In JavaScript:
- look at the beginning of the HTML source code of this page.
- In C:
static int gregorian = 1; // 1:Gregorian 0:Julian typedef struct{int day, month, year;} date; // 1..31, 1..12, ..2005.. int daynumber(date d) { // convert date into day number if(month<3){ d.year-=1; d.month+=12; } // move origin to march 1st return d.year*365 + d.year/4 + (gregorian ? -d.year/100 + d.year/400 : 0) + (d.month+1)*153/5-123 + d.day; } int weekday(int n) { // convert day number into: return (gregorian ? n+2 : n) % 7; // 0=monday .. 6=sunday } void daydate(int n, date *d) { // convert day number into date int m, y=0; if(gregorian) { m = n/146097; y += m*400; n -= m*146097; // 400 years periods if(j==146096) { d->an=a+400; d->mois=2; d->jour=29; return; } m = n/36524; y += m*100; n -= m*36524; // 100 years periods } m = n/1461; y += m*4; n -= m*1461; // 4 years periods if(n==1460) { d->year=y+4; d->month=2; d->day=29; return; } m = n/365; y += m; n -= m*365; // 1 year periods m = (n+31)*5/153+2; n -= (m+1)*153/5-123; if(m>12) { y+=1; m-=12; } // restore origin to january 1st d->year=y; d->month=m; d->day=n; return; }

- In Forth :
1 value gregorian \ 1:Gregorian 0:Julian : date> \ d m y -- n ; convert date m/d/y into day number n >r dup 3 < IF 12 + r> 1- >r THEN \ move origin to march 1st 1+ 153 * 5 / 123 - + \ -- n | y ; n days from 3/1/y au m/d/y r@ 4 / + gregorian IF r@ 100 / - r@ 400 / + THEN r> 365 * + ; : >weekday \ n -- w ; convert day number n into: gregorian IF 2 + THEN 7 mod \ 0:monday .. 6:sunday ; : >date \ n -- d m y ; convert day number n into date m/d/y 0 >r gregorian IF 146097 /mod 400 * r> + >r \ 400 years periods 146096 over = IF drop 29 2 r> 400 + exit THEN 36524 /mod 100 * r> + >r \ 100 years periods THEN \ -- n | y 1461 /mod 4 * r> + >r \ 4 years periods 1460 over = IF drop 29 2 r> 4 + exit THEN 365 /mod r> + >r \ 1 year periods dup 31 + 5 * 153 / 2 + tuck 1+ 153 * 5 / 123 - - swap \ -- d m | y dup 12 > IF 12 - r> 1+ >r THEN r> \ -- d m y ;