The Julian day number conversions are inverse bijections full
This proof shows: correctness.
Claim. Let G be the set of valid dates (Y,M,D) of the proleptic Gregorian calendar, with Y∈Z, 1≤M≤12 and 1≤D≤ℓ(Y,M), the length of month M in year Y. Let succ be the map that sends each date to the next day. Then:
- JDN-FROM-DATE (lines L1 to L4) satisfies J(succ(Y,M,D))=J(Y,M,D)+1 for each date, and J(−4713,11,24)=0. So it numbers the days consecutively, with day 0 on 24 November −4713, and it is a bijection from G to Z.
- DATE-FROM-JDN (lines L5 to L14) returns, for each integer J, the date in G whose number is J.
Throughout, ⌊⋅⌋ is floor division, defined for all integers.
A floor lemma. For integers x, a and q≥1: ⌊x/q⌋≤a⟺x≤qa+q−1. Indeed ⌊x/q⌋≤a⟺x/q<a+1⟺x<q(a+1)⟺x≤qa+q−1. Consequently, for an integer p≥1 and an integer t, the largest integer b with ⌊pb/q⌋≤t is ⌊(qt+q−1)/p⌋, because ⌊pb/q⌋≤t⟺pb≤qt+q−1⟺b≤(qt+q−1)/p.
March-based coordinates. For a date (Y,M,D), lines L1 to L3 compute a=⌊(14−M)/12⌋, which is 1 for M∈{1,2} and 0 for 3≤M≤12; then y=Y+4800−a and m=M+12a−3, so m=M−3∈{0,…,9} for March to December and m=M+9∈{10,11} for January and February. The map (Y,M)↦(y,m) is a bijection from Z×{1,…,12} to Z×{0,…,11}, with inverse M=m+3−12⌊m/10⌋ and Y=y−4800+⌊m/10⌋, since ⌊m/10⌋=a. Call the twelve months with the same y the March-year y; it runs from 1 March of civil year y−4800 to the last day of February of civil year y−4799.
Month offsets. Let f(m)=⌊(153m+2)/5⌋. Direct evaluation gives f(0),…,f(11)=0,31,61,92,122,153,184,214,245,275,306,337, and f(12)=367. The differences f(m+1)−f(m) for m=0,…,10 are 31,30,31,30,31,31,30,31,30,31,31, the lengths of March to January. So f(m) is the number of days from 1 March to the first day of month m of the same March-year, for 0≤m≤11.
Year lengths. The March-year y ends with February of civil year y−4799, so it has 366 days if that year is a leap year and 365 otherwise. Since 4800=12⋅400, the civil year y−4799 satisfies the leap rule (divisible by 4, and not by 100 unless by 400) if and only if y+1 does. Let χ(z)=1 if z satisfies the leap rule and 0 otherwise. Let L(y)=⌊y/4⌋−⌊y/100⌋+⌊y/400⌋. For each q≥1, ⌊z/q⌋−⌊(z−1)/q⌋ is 1 if q∣z and 0 otherwise. So L(z)−L(z−1)=[4∣z]−[100∣z]+[400∣z]=χ(z), by cases on the divisibility of z. Let N(y)=365y+L(y). Then for every integer y,
N(y+1)−N(y)=365+χ(y+1)=the length of March-year y. So N(y) is the number of days from 1 March of March-year 0 to 1 March of March-year y (negative for y<0), with N(0)=0.
Part 1. Line L4 returns J=D−1+f(m)+N(y)−32044. By the last two paragraphs, D−1+f(m)+N(y) is the number of days from 1 March of March-year 0 (1 March −4800) to the given date. Each step to the next day raises this count by one: within a month D grows by one; from the last day of month m<11 to the first of month m+1, the term D−1+f(m) goes from f(m+1)−f(m)−1+f(m) to f(m+1); from the last day of month 11 (which has N(y+1)−N(y)−f(11) days) to 1 March of year y+1 the count goes from N(y+1)−1 to N(y+1). So J(succ(x))=J(x)+1. For 24 November −4713: a=0, y=87, m=8, and J=24+245+31755+21−0+0−32045=0. A map from G to Z that sends one date to 0 and each successor to the next integer is a bijection, since succ is a bijection of G and every date is reached from 24 November −4713 by a finite number of steps forward or backward.
Part 2. Let J be an integer and let (Y∗,M∗,D∗) be its date from Part 1, with March-based coordinates (y∗,m∗) and e∗=D∗−1+f(m∗), so that a=J+32044=N(y∗)+e∗ by Part 1 and line L5, with 0≤e∗<N(y∗+1)−N(y∗).
Centuries (lines L6 and L7). For an integer b, N(100b)=36500b+25b−b+⌊b/4⌋=36524b+⌊b/4⌋=⌊146097b/4⌋. The function N is strictly increasing, so the largest b with N(100b)≤a is the one with 100b≤y∗<100(b+1), that is, b=⌊y∗/100⌋. By the floor lemma with p=146097 and q=4, this b is ⌊(4a+3)/146097⌋, which is line L6. Line L7 sets c=a−N(100b), the number of days from the start of March-year 100b to the date, so c≥0.
Years (lines L8 and L9). Let d∗=y∗−100b, so 0≤d∗≤99. For 0≤d≤99, the March-years 100b,…,100b+d−1 have leap days exactly when χ(z)=1 for z=100b+1,…,100b+d. None of these z is a multiple of 100, so χ(z)=[4∣z], and their number is ⌊d/4⌋ because 100b is a multiple of 4. Hence N(100b+d)−N(100b)=365d+⌊d/4⌋=⌊1461d/4⌋ for 0≤d≤99. Let g(d)=⌊1461d/4⌋; it is strictly increasing in d. We have g(d∗)≤c, and we claim c<g(d∗+1). If d∗≤98, then g(d∗+1)=N(y∗+1)−N(100b)>c. If d∗=99, then c<N(100b+100)−N(100b)≤36525=g(100). So d∗ is the largest d with g(d)≤c, and by the floor lemma with p=1461 and q=4, it equals ⌊(4c+3)/1461⌋, which is line L8. Line L9 gives e=c−g(d∗)=a−N(y∗)=e∗.
Months (lines L10 and L11). Here 0≤e∗≤365, and f(m∗)≤e∗<f(m∗+1) for m∗≤10, while for m∗=11, f(11)=337≤e∗≤365<367=f(12). Since f is strictly increasing, m∗ is the largest m with f(m)≤e∗. By the floor lemma with p=153, q=5 and the offset +2 (that is, f(m)≤e⟺153m+2≤5e+4⟺m≤(5e+2)/153), it is ⌊(5e∗+2)/153⌋, which is line L10. Line L11 gives D=e∗−f(m∗)+1=D∗.
Back to the civil year (lines L12 and L13). With y∗=100b+d∗, lines L12 and L13 apply the inverse of the March-based coordinates, so they return M∗ and Y∗=y∗−4800+⌊m∗/10⌋.
So DATE-FROM-JDN(J)=(Y∗,M∗,D∗) for every integer J, and the two procedures are inverse bijections between G and Z.
The Julian calendar block. The same argument holds with χ(z)=[4∣z], L(y)=⌊y/4⌋ and N(y)=365y+⌊y/4⌋=⌊1461y/4⌋, without the century step. The constant −32083 makes 1 January −4712 day 0: a=1, y=87, m=10 and 1+306+31755+21−32083=0. In the inverse, c=J+32082 is the count from 1 March −4800 of the Julian calendar, and d=⌊(4c+3)/1461⌋ is the March-year, by the floor lemma. ■