-
-
Save GeeLaw/9c68befab1b125a33c52deaf386bf92a to your computer and use it in GitHub Desktop.
Find out `a-b-c` is `u-v-w` after `x-y-z` (`yyyy-MM-dd`).
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
/* https://www.v2ex.com/t/879372 */ | |
int days_in_month(int m) | |
{ | |
switch (m % 12) | |
{ | |
case 0: case 2: case 4: case 6: case 7: case 9: case 11: | |
return 31; | |
case 3: case 5: case 8: case 10: | |
return 30; | |
case 2: default: | |
m /= 12; | |
return m % 3200 == 0 ? 28 | |
: m % 400 == 0 ? 29 | |
: m % 100 == 0 ? 28 | |
: m % 4 == 0 ? 29 | |
: 28; | |
} | |
} | |
/* yyyy-MM-dd: a-b-c is u-v-w after x-y-z. */ | |
void pretty_date_diff | |
( | |
int a, int b, int c, | |
int x, int y, int z, | |
int *u, int *v, int *w | |
) | |
{ | |
/* Error checks are elided. */ | |
int aligned_month = a * 12 + (b - 1); | |
int days = c - z; | |
if (days < 0) | |
{ | |
--aligned_month; | |
days += days_in_month(aligned_month); | |
} | |
/* "days < 0" is still possible here, but | |
/* if so, the following branch will be taken. */ | |
if (z > days_in_month(aligned_month)) | |
{ | |
--aligned_month; | |
z += 31; | |
} | |
int months_passed = aligned_month - x * 12 - (y - 1); | |
*u = months_passed / 12; | |
*v = months_passed % 12; | |
*w = days; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment