Created
July 19, 2012 06:52
-
-
Save cjheath/3141204 to your computer and use it in GitHub Desktop.
Conversion of year/month/day to day since epoch, and back (with weekday)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define OFFS -306 /* Offset to epoch-day (Day 1 is 1/1/0001) */ | |
#define WD 0L /* Day of week offset */ | |
/* | |
* datol: takes a YMD date, and returns the number of days since some base | |
* date (in the very distant past). | |
* | |
* Handy for getting date of x number of days before/after a given date. | |
* A date is valid if ltodate() yields the same YMD you started with. | |
* | |
* Translated to C by Clifford Heath from Nat Howard's Fortran translation | |
* of the Algol original by Robert G. Tantzen, as published in Collected | |
* Algorithms of the ACM (CACM algorithm 199) | |
*/ | |
static long | |
datol( | |
int year, | |
int mon, | |
int day | |
) | |
{ | |
if (mon < 3) /* Adjust for February. */ | |
mon += 9, --year; | |
else | |
mon -= 3; | |
return ((146097L * (year/100L)) / 4L) /* Century days */ | |
+ ((1461L * (year%100)) / 4L) /* Year days */ | |
+ ((153L*mon + 2L) / 5L) /* Add adjustment for month */ | |
+ day /* Add day */ | |
+ OFFS; /* Add offset */ | |
} | |
/* | |
* ltodate: Convert day since epoch to date. | |
* | |
* Returns day of the week (0 = Sunday to 6 = Saturday) | |
* and sets ymd[3]: | |
* ymd[0] = year (actual year, like 1977, not 77 unless it was 77 a.d.); | |
* ymd[1] = month; | |
* ymd[2] = day of month; | |
*/ | |
static int | |
ltodate( | |
long j, | |
int ymd[3] | |
) | |
{ | |
long d, m, y, wd; | |
wd = (j + WD)%7L; | |
j -= OFFS; | |
y = (4L * j - 1L)/146097L; | |
j = 4L * j - 1L - 146097L * y; | |
d = j/4L; | |
j = (4L * d + 3L)/1461L; | |
d = 4L * d + 3L - 1461L * j; | |
d = (d + 4L)/4L; | |
m = (5L * d - 3L)/153L; | |
d = 5L * d - 3 - 153L * m; | |
d = (d + 5L) / 5L; | |
y = 100L * y + j; | |
if (m < 10) | |
m += 3; | |
else { | |
m -= 9; | |
++y; | |
} | |
ymd[0] = (int) y; | |
ymd[1] = (int) m; | |
ymd[2] = (int) d; | |
return wd; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment