rework langinfo code for ABI compat and for use by time code
[musl] / src / time / __year_to_secs.c
1 long long __year_to_secs(long long year, int *is_leap)
2 {
3         if (year-2ULL <= 136) {
4                 int y = year;
5                 int leaps = (y-68)>>2;
6                 if (!((y-68)&3)) {
7                         leaps--;
8                         if (is_leap) *is_leap = 1;
9                 } else if (is_leap) *is_leap = 0;
10                 return 31536000*(y-70) + 86400*leaps;
11         }
12
13         int cycles, centuries, leaps, rem;
14
15         if (!is_leap) is_leap = &(int){0};
16         cycles = (year-100) / 400;
17         rem = (year-100) % 400;
18         if (rem < 0) {
19                 cycles--;
20                 rem += 400;
21         }
22         if (!rem) {
23                 *is_leap = 1;
24                 centuries = 0;
25                 leaps = 0;
26         } else {
27                 if (rem >= 200) {
28                         if (rem >= 300) centuries = 3, rem -= 300;
29                         else centuries = 2, rem -= 200;
30                 } else {
31                         if (rem >= 100) centuries = 1, rem -= 100;
32                         else centuries = 0;
33                 }
34                 if (!rem) {
35                         *is_leap = 0;
36                         leaps = 0;
37                 } else {
38                         leaps = rem / 4U;
39                         rem %= 4U;
40                         *is_leap = !rem;
41                 }
42         }
43
44         leaps += 97*cycles + 24*centuries - *is_leap;
45
46         return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
47 }