|
nsz |
73214b |
#define _XOPEN_SOURCE 700
|
|
nsz |
73214b |
#include <stdlib.h>
|
|
nsz |
73214b |
#include <stdio.h>
|
|
nsz |
73214b |
#include <time.h>
|
|
nsz |
73214b |
#include "test.h"
|
|
nsz |
73214b |
|
|
nsz |
73214b |
/* We use this instead of memcmp because some broken C libraries
|
|
nsz |
73214b |
* add additional nonstandard fields to struct tm... */
|
|
nsz |
73214b |
|
|
nsz |
73214b |
int tm_cmp(struct tm tm1, struct tm tm2)
|
|
nsz |
73214b |
{
|
|
nsz |
73214b |
return tm1.tm_sec != tm2.tm_sec ||
|
|
nsz |
73214b |
tm1.tm_min != tm2.tm_min ||
|
|
nsz |
73214b |
tm1.tm_hour != tm2.tm_hour ||
|
|
nsz |
73214b |
tm1.tm_mday != tm2.tm_mday ||
|
|
nsz |
73214b |
tm1.tm_mon != tm2.tm_mon ||
|
|
nsz |
73214b |
tm1.tm_year != tm2.tm_year ||
|
|
nsz |
73214b |
tm1.tm_wday != tm2.tm_wday ||
|
|
nsz |
73214b |
tm1.tm_yday != tm2.tm_yday ||
|
|
nsz |
73214b |
tm1.tm_isdst!= tm2.tm_isdst;
|
|
nsz |
73214b |
}
|
|
nsz |
73214b |
|
|
nsz |
73214b |
char *tm_str(struct tm tm)
|
|
nsz |
73214b |
{
|
|
nsz |
73214b |
static int i;
|
|
nsz |
73214b |
static char b[4][64];
|
|
nsz |
73214b |
i = (i+1)%4;
|
|
nsz |
73214b |
snprintf(b[i], sizeof b[i],
|
|
nsz |
73214b |
"s=%02d m=%02d h=%02d mday=%02d mon=%02d year=%04d wday=%d yday=%d isdst=%d",
|
|
nsz |
73214b |
tm.tm_sec, tm.tm_min, tm.tm_hour,
|
|
nsz |
73214b |
tm.tm_mday, tm.tm_mon, tm.tm_year,
|
|
nsz |
73214b |
tm.tm_wday, tm.tm_yday, tm.tm_isdst);
|
|
nsz |
73214b |
return b[i];
|
|
nsz |
73214b |
}
|
|
nsz |
73214b |
|
|
nsz |
73214b |
#define TM(ss,mm,hh,md,mo,yr,wd,yd,dst) (struct tm){ \
|
|
nsz |
73214b |
.tm_sec = ss, .tm_min = mm, .tm_hour = hh, \
|
|
nsz |
73214b |
.tm_mday = md, .tm_mon = mo, .tm_year = yr, \
|
|
nsz |
73214b |
.tm_wday = wd, .tm_yday = yd, .tm_isdst = dst }
|
|
nsz |
73214b |
|
|
nsz |
73214b |
#define TM_EPOCH TM(0,0,0,1,0,70,4,0,0)
|
|
nsz |
73214b |
#define TM_Y2038_1S TM(7,14,3,19,0,138,2,18,0)
|
|
nsz |
73214b |
#define TM_Y2038 TM(8,14,3,19,0,138,2,18,0)
|
|
nsz |
73214b |
|
|
nsz |
73214b |
#define TEST_TM(r,x,m) (!tm_cmp((r),(x)) || \
|
|
nsz |
73214b |
(error("%s failed:\n\tresult: %s\n\texpect: %s\n", \
|
|
nsz |
73214b |
m, tm_str(r), tm_str(x)), 0) )
|
|
nsz |
73214b |
|
|
nsz |
73214b |
#define TEST(r, f, x, m) ( \
|
|
nsz |
73214b |
((r) = (f)) == (x) || \
|
|
nsz |
73214b |
(error("%s failed (" m ")\n", #f, r, x), 0) )
|
|
nsz |
73214b |
|
|
nsz |
73214b |
void test_time(void) {
|
|
nsz |
73214b |
struct tm tm, *tm_p;
|
|
nsz |
73214b |
time_t t;
|
|
nsz |
73214b |
|
|
nsz |
73214b |
putenv("TZ=GMT");
|
|
nsz |
73214b |
tzset();
|
|
nsz |
73214b |
|
|
nsz |
73214b |
t=0; tm_p = gmtime(&t);
|
|
nsz |
73214b |
TEST_TM(*tm_p, TM_EPOCH, "gmtime(0)");
|
|
nsz |
73214b |
|
|
nsz |
73214b |
tm = TM_Y2038_1S;
|
|
nsz |
73214b |
t = mktime(&tm;;
|
|
nsz |
73214b |
tm = *(gmtime(&t);;
|
|
nsz |
73214b |
TEST_TM(*tm_p, TM_Y2038_1S, "mktime/gmtime(Y2038-1)");
|
|
nsz |
73214b |
|
|
nsz |
73214b |
tm = TM_Y2038;
|
|
nsz |
73214b |
t = mktime(&tm;;
|
|
nsz |
73214b |
tm = *(gmtime(&t);;
|
|
nsz |
73214b |
TEST_TM(*tm_p, TM_Y2038, "mktime/gmtime(Y2038)");
|
|
nsz |
73214b |
|
|
nsz |
73214b |
/* FIXME: set a TZ var and check DST boundary conditions */
|
|
nsz |
73214b |
}
|