Introduction
Introduction Statistics Contact Development Disclaimer Help
sfeed_time_libc.c - sfeed_tests - sfeed tests and RSS and Atom files
git clone git://git.codemadness.org/sfeed_tests
Log
Files
Refs
README
LICENSE
---
sfeed_time_libc.c (3196B)
---
1 /*
2 Test datetounix against timegm() libc implementation.
3
4 Extract datetounix() function from sfeed.c:
5
6 echo 'static long long'
7 awk '/^datetounix/ { d=1; } d && /^}$/ { exit(0); } d' < sfeed.c
8 echo '}'
9 */
10
11 #include <err.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <time.h>
16
17 static long long
18 datetounix(long long year, int mon, int day, int hour, int min, int sec)
19 {
20 /* seconds in a month in a regular (non-leap) year */
21 static const long secs_through_month[] = {
22 0, 31 * 86400, 59 * 86400, 90 * 86400,
23 120 * 86400, 151 * 86400, 181 * 86400, 212 * 86400,
24 243 * 86400, 273 * 86400, 304 * 86400, 334 * 86400 };
25 int is_leap = 0, cycles, centuries = 0, leaps = 0, rem;
26 long long t;
27
28 /* optimization: handle common range year 1902 up to and includi…
29 if (year - 2ULL <= 136) {
30 /* amount of leap days relative to 1970: every 4 years */
31 leaps = (year - 68) >> 2;
32 if (!((year - 68) & 3)) {
33 leaps--;
34 is_leap = 1;
35 } else {
36 is_leap = 0;
37 }
38 t = 31536000 * (year - 70) + (86400 * leaps); /* 365 * 8…
39 } else {
40 /* general leap year calculation:
41 leap years occur mostly every 4 years but every 100 y…
42 a leap year is skipped unless the year is divisible b…
43 cycles = (year - 100) / 400;
44 rem = (year - 100) % 400;
45 if (rem < 0) {
46 cycles--;
47 rem += 400;
48 }
49 if (!rem) {
50 is_leap = 1;
51 } else {
52 if (rem >= 300) {
53 centuries = 3;
54 rem -= 300;
55 } else if (rem >= 200) {
56 centuries = 2;
57 rem -= 200;
58 } else if (rem >= 100) {
59 centuries = 1;
60 rem -= 100;
61 }
62 if (rem) {
63 leaps = rem / 4U;
64 rem %= 4U;
65 is_leap = !rem;
66 }
67 }
68 leaps += (97 * cycles) + (24 * centuries) - is_leap;
69
70 /* adjust 8 leap days from 1970 up to and including 2000:
71 ((30 * 365) + 8) * 86400 = 946771200 */
72 t = ((year - 100) * 31536000LL) + (leaps * 86400LL) + 94…
73 }
74 t += secs_through_month[mon];
75 if (is_leap && mon >= 2)
76 t += 86400;
77 t += 86400LL * (day - 1);
78 t += 3600LL * hour;
79 t += 60LL * min;
80 t += sec;
81
82 return t;
83 }
84
85 void
86 testtm(struct tm *tm)
87 {
88 time_t t1, t2; /* assume time_t is signed 64-bit */
89 long long ll;
90
91 t1 = timegm(tm);
92 if (t1 == (time_t)-1) {
93 errx(1, "timegm failed for %d, %d, %d, %d, %d, %d\n",
94 tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hou…
95 }
96
97 ll = datetounix(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hou…
98 t2 = (time_t)ll;
99
100 if (t1 != t2) {
101 printf("result: %lld != %lld\n", (long long)t1, (long lo…
102 printf("for: %d, %d, %d, %d, %d, %d\n",
103 tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hou…
104 exit(1);
105 }
106 }
107
108 int
109 main(void)
110 {
111 struct tm tm;
112 int y, mon, d;
113 long long counter = 0;
114
115 for (y = -2069; y < 2069; y++) {
116 for (mon = 0; mon < 12; mon++) {
117 for (d = 1; d <= 31; d++) {
118 /* printf("DEBUG: comparing %d %d %d\n", …
119
120 memset(&tm, 0, sizeof(tm));
121 tm.tm_year = y - 1900;
122 tm.tm_mon = mon - 1;
123 tm.tm_mday = d;
124 tm.tm_hour = 0;
125 tm.tm_min = 0;
126 tm.tm_sec = 0;
127 tm.tm_isdst = -1;
128
129 testtm(&tm);
130 counter++;
131 }
132 }
133 }
134 printf("%lld dates compared, all OK\n", counter);
135
136 return 0;
137 }
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.