Package Gnumed :: Package timelinelib :: Package calendar :: Package gregorian :: Module gregorian
[frames] | no frames]

Module gregorian

source code

Classes
  GregorianDateTime
Functions
 
days_in_month(year, month) source code
 
is_leap_year(year) source code
 
is_valid_time(hour, minute, second) source code
 
is_valid(year, month, day) source code
 
julian_day_to_gregorian_ymd(julian_day)
This algorithm is described here:
source code
 
gregorian_ymd_to_julian_day(year, month, day)
This algorithm is described here:
source code

Imports: GregorianDelta, GregorianTime


Function Details

julian_day_to_gregorian_ymd(julian_day)

source code 

This algorithm is described here:

* http://www.tondering.dk/claus/cal/julperiod.php#formula

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).

gregorian_ymd_to_julian_day(year, month, day)

source code 

This algorithm is described here:

* http://www.tondering.dk/claus/cal/julperiod.php#formula
* http://en.wikipedia.org/wiki/Julian_day#Converting_Julian_or_Gregorian_calendar_date_to_Julian_Day_Number

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 sources 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) y >= 0
2) ((153 * m) + 2) >= 0

Let's prove 1):

y = year + 4800 - a
  = year + 4800 - ((14 - month) // 12)

year >= -4713 (gives a julian day of 0)

so

year + 4800 >= -4713 + 4800 = 87

The expression ((14 - month) // 12) varies between 0 and 1 when month
varies between 1 and 12. Therefore y >= 87 - 1 = 86, and 1) is proved.

Let's prove 2):

m = month + (12 * a) - 3
  = month + (12 * ((14 - month) // 12)) - 3

1 <= month <= 12

m(1)  = 1  + (12 * ((14 - 1)  // 12)) - 3 = 1  + (12 * 1) - 3 = 10
m(2)  = 2  + (12 * ((14 - 2)  // 12)) - 3 = 2  + (12 * 1) - 3 = 11
m(3)  = 3  + (12 * ((14 - 3)  // 12)) - 3 = 3  + (12 * 0) - 3 = 0
m(4)  = 4  + (12 * ((14 - 4)  // 12)) - 3 = 4  + (12 * 0) - 3 = 1
m(5)  = 5  + (12 * ((14 - 5)  // 12)) - 3 = 5  + (12 * 0) - 3 = 2
m(6)  = 6  + (12 * ((14 - 6)  // 12)) - 3 = 6  + (12 * 0) - 3 = 3
m(7)  = 7  + (12 * ((14 - 7)  // 12)) - 3 = 7  + (12 * 0) - 3 = 4
m(8)  = 8  + (12 * ((14 - 8)  // 12)) - 3 = 8  + (12 * 0) - 3 = 5
m(9)  = 9  + (12 * ((14 - 9)  // 12)) - 3 = 9  + (12 * 0) - 3 = 6
m(10) = 10 + (12 * ((14 - 10) // 12)) - 3 = 10 + (12 * 0) - 3 = 7
m(11) = 11 + (12 * ((14 - 11) // 12)) - 3 = 11 + (12 * 0) - 3 = 8
m(12) = 12 + (12 * ((14 - 12) // 12)) - 3 = 12 + (12 * 0) - 3 = 9

So, m is always > 0. Which also makes the expression ((153 * m) + 2) > 0,
and 2) is proved.