module timelinelib.calendar.gregorian.julian2gregorian

Contains the GregorianDateTime class and static functions related to the class.

Tests are found here.

timelinelib.calendar.gregorian.julian2gregorian.julian_day_to_gregorian_ymd(julian_day)[source]

This algorithm is described here:

Integer division works differently in C and in Python for negative numbers. C truncates towards 0 and Python truncates towards negative infinity: http://python-history.blogspot.se/2010/08/why-pythons-integer-division-floors.html

The above source don’t state which to be used. If we can prove that division-expressions are always positive, we can be sure this algorithm works the same in C and in Python.

We must prove that:

  1. m >= 0

  2. ((5 * e) + 2) >= 0 => e >= 0

  3. (1461 * d) >= 0 => d >= 0

  4. ((4 * c) + 3) >= 0 => c >= 0

  5. (b * 146097) >= 0 => b >= 0

  6. ((4 * a) + 3) >= 0 => a >= 0

Let’s work from the top:

julian_day >= 0 =>

a >= 0 + 32044

= 32044 =>

This proves 6).

b >= ((4 * 32044) + 3) // 146097

= 0

This proves 5).

Let’s look at c:

c = a - ((b * 146097) // 4)

= a - (((((4 * a) + 3) // 146097) * 146097) // 4)

For c to be >= 0, then

(((((4 * a) + 3) // 146097) * 146097) // 4) <= a

Let’s look at this component: ((((4 * a) + 3) // 146097) * 146097)

This expression can never be larger than (4 * a) + 3. That gives this:

((4 * a) + 3) // 4 <= a, which holds.

This proves 4).

Now, let’s look at d:

d = ((4 * c) + 3) // 1461

If c is >= 0, then d is also >= 0.

This proves 3).

Let’s look at e:

e = c - ((1461 * d) // 4)

= c - ((1461 * (((4 * c) + 3) // 1461)) // 4)

The same resoning as above can be used to conclude that e >= 0.

This proves 2).

Now, let’s look at m:

m = ((5 * e) + 2) // 153

If e >= 0, then m is also >= 0.

This proves 1).