Skip to content

Instantly share code, notes, and snippets.

@GeeLaw
Created September 12, 2022 04:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GeeLaw/9c68befab1b125a33c52deaf386bf92a to your computer and use it in GitHub Desktop.
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`).
/* 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