1 #define _XOPEN_SOURCE 700
10 /* We use this instead of memcmp because some broken C libraries
11 * add additional nonstandard fields to struct tm... */
13 int tm_cmp(struct tm tm1
, struct tm tm2
)
15 return tm1
.tm_sec
!= tm2
.tm_sec
||
16 tm1
.tm_min
!= tm2
.tm_min
||
17 tm1
.tm_hour
!= tm2
.tm_hour
||
18 tm1
.tm_mday
!= tm2
.tm_mday
||
19 tm1
.tm_mon
!= tm2
.tm_mon
||
20 tm1
.tm_year
!= tm2
.tm_year
||
21 tm1
.tm_wday
!= tm2
.tm_wday
||
22 tm1
.tm_yday
!= tm2
.tm_yday
||
23 tm1
.tm_isdst
!= tm2
.tm_isdst
;
26 char *tm_str(struct tm tm
)
31 snprintf(b
[i
], sizeof b
[i
],
32 "s=%02d m=%02d h=%02d mday=%02d mon=%02d year=%04d wday=%d yday=%d isdst=%d",
33 tm
.tm_sec
, tm
.tm_min
, tm
.tm_hour
,
34 tm
.tm_mday
, tm
.tm_mon
, tm
.tm_year
,
35 tm
.tm_wday
, tm
.tm_yday
, tm
.tm_isdst
);
39 #define TM(ss,mm,hh,md,mo,yr,wd,yd,dst) (struct tm){ \
40 .tm_sec = ss, .tm_min = mm, .tm_hour = hh, \
41 .tm_mday = md, .tm_mon = mo, .tm_year = yr, \
42 .tm_wday = wd, .tm_yday = yd, .tm_isdst = dst }
44 #define TM_EPOCH TM(0,0,0,1,0,70,4,0,0)
45 #define TM_Y2038_1S TM(7,14,3,19,0,138,2,18,0)
46 #define TM_Y2038 TM(8,14,3,19,0,138,2,18,0)
48 static void sec2tm(time_t t
, char *m
)
56 t_error("%s: gmtime((time_t)%lld) should not set errno, got %s\n",
57 m
, (long long)t
, strerror(errno
));
61 t_error("%s: mktime(%s) should not set errno, got %s\n",
62 m
, tm_str(*tm
), strerror(errno
));
64 t_error("%s: mktime(gmtime(%lld)) roundtrip failed: got %lld (gmtime is %s)\n",
65 m
, (long long)t
, (long long)r
, tm_str(*tm
));
68 static void tm2sec(struct tm
*tm
, int big
, char *m
)
72 int overflow
= big
&& (time_t)LLONG_MAX
!=LLONG_MAX
;
76 if (overflow
&& t
!= -1)
77 t_error("%s: mktime(%s) expected -1, got (time_t)%ld\n",
78 m
, tm_str(*tm
), (long)t
);
79 if (overflow
&& errno
!= EOVERFLOW
)
80 t_error("%s: mktime(%s) expected EOVERFLOW (%s), got (%s)\n",
81 m
, tm_str(*tm
), strerror(EOVERFLOW
), strerror(errno
));
82 if (!overflow
&& t
== -1)
83 t_error("%s: mktime(%s) expected success, got (time_t)-1\n",
85 if (!overflow
&& errno
)
86 t_error("%s: mktime(%s) expected no error, got (%s)\n",
87 m
, tm_str(*tm
), strerror(errno
));
89 if (!overflow
&& tm_cmp(*r
, *tm
))
90 t_error("%s: gmtime(mktime(%s)) roundtrip failed: got %s\n",
91 m
, tm_str(*tm
), tm_str(*r
));
100 tm2sec(&TM_EPOCH
, 0, "gmtime(0)");
101 tm2sec(&TM_Y2038_1S
, 0, "2038-1s");
102 tm2sec(&TM_Y2038
, 1, "2038");
105 for (t
= 1; t
< 1000; t
++)
106 sec2tm(t
*100003, "EPOCH+eps");
108 /* FIXME: set a TZ var and check DST boundary conditions */