- // TODO this probably could be optimised somehow...
-
- double jdn = (timeMidnight / MILLISECONDS_PER_DAY).GetLo();
- jdn += EPOCH_JDN + 0.5;
- long z = jdn - 1721118.5;
- double r = jdn - 1721118.5 - z;
- double g = z - 0.25;
- long a = g/36524.25; // number of days per year
- long b = a - a / 4;
- int year = (b + g) / 365.25;
- long c = b + z - 365.25*year;
- int month = (5*c + 456)/153;
- int day = c - (153*month - 457)/5 + (r < 0.5 ? 0 : 1);
- if ( month > 12 )
+ // calculate the Gregorian date from JDN for the midnight of our date:
+ // this will yield day, month (in 1..12 range) and year
+
+ // actually, this is the JDN for the noon of the previous day
+ long jdn = (timeMidnight / MILLISECONDS_PER_DAY).ToLong() + EPOCH_JDN;
+
+ // CREDIT: code below is by Scott E. Lee (but bugs are mine)
+
+ wxASSERT_MSG( jdn > -2, _T("JDN out of range") );
+
+ // calculate the century
+ int temp = (jdn + JDN_OFFSET) * 4 - 1;
+ int century = temp / DAYS_PER_400_YEARS;
+
+ // then the year and day of year (1 <= dayOfYear <= 366)
+ temp = ((temp % DAYS_PER_400_YEARS) / 4) * 4 + 3;
+ int year = (century * 100) + (temp / DAYS_PER_4_YEARS);
+ int dayOfYear = (temp % DAYS_PER_4_YEARS) / 4 + 1;
+
+ // and finally the month and day of the month
+ temp = dayOfYear * 5 - 3;
+ int month = temp / DAYS_PER_5_MONTHS;
+ int day = (temp % DAYS_PER_5_MONTHS) / 5 + 1;
+
+ // month is counted from March - convert to normal
+ if ( month < 10 )