--- /dev/null
+/* $OpenBSD: timetest.c,v 1.1 2022/11/06 12:57:08 beck Exp $ */
+
+/*
+ * Copyright (c) 2022 Bob Beck <beck@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/stat.h>
+#include <sys/stdint.h>
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+struct timetest {
+ char *descr;
+ char *timezone;
+ time_t time;
+ struct tm local_tm;
+ struct tm gmt_tm;
+};
+
+static int tm_match(struct tm * tm1, struct tm *tm2) {
+ if (tm2->tm_year != tm1->tm_year ||
+ tm2->tm_mon != tm1->tm_mon ||
+ tm2->tm_mday != tm1->tm_mday ||
+ tm2->tm_hour != tm1->tm_hour ||
+ tm2->tm_min != tm1->tm_min ||
+ tm2->tm_sec != tm1->tm_sec ||
+ tm2->tm_wday != tm1->tm_wday ||
+ tm2->tm_yday != tm1->tm_yday ||
+ tm2->tm_yday != tm1->tm_yday ||
+ tm2->tm_isdst != tm1->tm_isdst ||
+ tm2->tm_gmtoff != tm1->tm_gmtoff ||
+ strcmp(tm2->tm_zone, tm1->tm_zone) != 0)
+ return 0;
+ return 1;
+}
+
+struct timetest timetests[] = {
+ {
+ .descr="moon",
+ .timezone="posix/America/Edmonton",
+ .time=-16751025,
+ .local_tm= {
+ .tm_year=69,
+ .tm_mon=5,
+ .tm_mday=20,
+ .tm_hour=19,
+ .tm_min=56,
+ .tm_sec=15,
+ .tm_wday=5,
+ .tm_yday=170,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=69,
+ .tm_mon=5,
+ .tm_mday=21,
+ .tm_hour=2,
+ .tm_min=56,
+ .tm_sec=15,
+ .tm_wday=6,
+ .tm_yday=171,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="moon",
+ .timezone="right/UTC",
+ .time=-16751025,
+ .local_tm= {
+ .tm_year=69,
+ .tm_mon=5,
+ .tm_mday=21,
+ .tm_hour=2,
+ .tm_min=56,
+ .tm_sec=15,
+ .tm_wday=6,
+ .tm_yday=171,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=69,
+ .tm_mon=5,
+ .tm_mday=21,
+ .tm_hour=2,
+ .tm_min=56,
+ .tm_sec=15,
+ .tm_wday=6,
+ .tm_yday=171,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="moon",
+ .timezone="right/America/Edmonton",
+ .time=-16751025,
+ .local_tm= {
+ .tm_year=69,
+ .tm_mon=5,
+ .tm_mday=20,
+ .tm_hour=19,
+ .tm_min=56,
+ .tm_sec=15,
+ .tm_wday=5,
+ .tm_yday=170,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=69,
+ .tm_mon=5,
+ .tm_mday=21,
+ .tm_hour=2,
+ .tm_min=56,
+ .tm_sec=15,
+ .tm_wday=6,
+ .tm_yday=171,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="epoch",
+ .timezone="posix/America/Edmonton",
+ .time=0,
+ .local_tm= {
+ .tm_year=69,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=17,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=3,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=70,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=4,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="epoch",
+ .timezone="right/UTC",
+ .time=0,
+ .local_tm= {
+ .tm_year=70,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=4,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=70,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=4,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="epoch",
+ .timezone="right/America/Edmonton",
+ .time=0,
+ .local_tm= {
+ .tm_year=69,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=17,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=3,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=70,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=4,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="epoch - 1",
+ .timezone="posix/America/Edmonton",
+ .time=-1,
+ .local_tm= {
+ .tm_year=69,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=16,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=3,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=69,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=3,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="epoch - 1",
+ .timezone="right/UTC",
+ .time=-1,
+ .local_tm= {
+ .tm_year=69,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=3,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=69,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=3,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="epoch - 1",
+ .timezone="right/America/Edmonton",
+ .time=-1,
+ .local_tm= {
+ .tm_year=69,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=16,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=3,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=69,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=3,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="legacy min",
+ .timezone="posix/America/Edmonton",
+ .time=-2147483648,
+ .local_tm= {
+ .tm_year=1,
+ .tm_mon=11,
+ .tm_mday=13,
+ .tm_hour=13,
+ .tm_min=12,
+ .tm_sec=0,
+ .tm_wday=5,
+ .tm_yday=346,
+ .tm_isdst=0,
+ .tm_gmtoff=-27232,
+ .tm_zone="LMT"
+ },
+ .gmt_tm= {
+ .tm_year=1,
+ .tm_mon=11,
+ .tm_mday=13,
+ .tm_hour=20,
+ .tm_min=45,
+ .tm_sec=52,
+ .tm_wday=5,
+ .tm_yday=346,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="legacy min",
+ .timezone="right/UTC",
+ .time=-2147483648,
+ .local_tm= {
+ .tm_year=1,
+ .tm_mon=11,
+ .tm_mday=13,
+ .tm_hour=20,
+ .tm_min=45,
+ .tm_sec=52,
+ .tm_wday=5,
+ .tm_yday=346,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=1,
+ .tm_mon=11,
+ .tm_mday=13,
+ .tm_hour=20,
+ .tm_min=45,
+ .tm_sec=52,
+ .tm_wday=5,
+ .tm_yday=346,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="legacy min - 1",
+ .timezone="posix/America/Edmonton",
+ .time=-2147483649,
+ .local_tm= {
+ .tm_year=1,
+ .tm_mon=11,
+ .tm_mday=13,
+ .tm_hour=13,
+ .tm_min=11,
+ .tm_sec=59,
+ .tm_wday=5,
+ .tm_yday=346,
+ .tm_isdst=0,
+ .tm_gmtoff=-27232,
+ .tm_zone="LMT"
+ },
+ .gmt_tm= {
+ .tm_year=1,
+ .tm_mon=11,
+ .tm_mday=13,
+ .tm_hour=20,
+ .tm_min=45,
+ .tm_sec=51,
+ .tm_wday=5,
+ .tm_yday=346,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="legacy min - 1",
+ .timezone="right/UTC",
+ .time=-2147483649,
+ .local_tm= {
+ .tm_year=1,
+ .tm_mon=11,
+ .tm_mday=13,
+ .tm_hour=20,
+ .tm_min=45,
+ .tm_sec=51,
+ .tm_wday=5,
+ .tm_yday=346,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=1,
+ .tm_mon=11,
+ .tm_mday=13,
+ .tm_hour=20,
+ .tm_min=45,
+ .tm_sec=51,
+ .tm_wday=5,
+ .tm_yday=346,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="legacy max",
+ .timezone="posix/America/Edmonton",
+ .time=2147483647,
+ .local_tm= {
+ .tm_year=138,
+ .tm_mon=0,
+ .tm_mday=18,
+ .tm_hour=20,
+ .tm_min=14,
+ .tm_sec=7,
+ .tm_wday=1,
+ .tm_yday=17,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=138,
+ .tm_mon=0,
+ .tm_mday=19,
+ .tm_hour=3,
+ .tm_min=14,
+ .tm_sec=7,
+ .tm_wday=2,
+ .tm_yday=18,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="legacy max",
+ .timezone="right/UTC",
+ .time=2147483647,
+ .local_tm= {
+ .tm_year=138,
+ .tm_mon=0,
+ .tm_mday=19,
+ .tm_hour=3,
+ .tm_min=13,
+ .tm_sec=40,
+ .tm_wday=2,
+ .tm_yday=18,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=138,
+ .tm_mon=0,
+ .tm_mday=19,
+ .tm_hour=3,
+ .tm_min=14,
+ .tm_sec=7,
+ .tm_wday=2,
+ .tm_yday=18,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="legacy max + 1",
+ .timezone="posix/America/Edmonton",
+ .time=2147483648,
+ .local_tm= {
+ .tm_year=138,
+ .tm_mon=0,
+ .tm_mday=18,
+ .tm_hour=20,
+ .tm_min=14,
+ .tm_sec=8,
+ .tm_wday=1,
+ .tm_yday=17,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=138,
+ .tm_mon=0,
+ .tm_mday=19,
+ .tm_hour=3,
+ .tm_min=14,
+ .tm_sec=8,
+ .tm_wday=2,
+ .tm_yday=18,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="legacy max + 1",
+ .timezone="right/UTC",
+ .time=2147483648,
+ .local_tm= {
+ .tm_year=138,
+ .tm_mon=0,
+ .tm_mday=19,
+ .tm_hour=3,
+ .tm_min=13,
+ .tm_sec=41,
+ .tm_wday=2,
+ .tm_yday=18,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=138,
+ .tm_mon=0,
+ .tm_mday=19,
+ .tm_hour=3,
+ .tm_min=14,
+ .tm_sec=8,
+ .tm_wday=2,
+ .tm_yday=18,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="min",
+ .timezone="posix/America/Edmonton",
+ .time=INT64_MIN,
+ .local_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ .gmt_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ },
+ {
+ .descr="min",
+ .timezone="right/UTC",
+ .time=INT64_MIN,
+ .local_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ .gmt_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ },
+ {
+ .descr="max",
+ .timezone="right/America/Edmonton",
+ .time=9223372036854775807,
+ .local_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ .gmt_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ },
+ {
+ .descr="max",
+ .timezone="posix/America/Edmonton",
+ .time=9223372036854775807,
+ .local_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ .gmt_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ },
+ {
+ .descr="max",
+ .timezone="right/UTC",
+ .time=9223372036854775807,
+ .local_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ .gmt_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ },
+ {
+ .descr="min",
+ .timezone="right/America/Edmonton",
+ .time=INT64_MIN,
+ .local_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ .gmt_tm= {
+ .tm_year=0,
+ .tm_mon=0,
+ .tm_mday=0,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="FAILURE"
+ },
+ },
+ {
+ .descr="0000",
+ .timezone="posix/America/Edmonton",
+ .time=-62167219200,
+ .local_tm= {
+ .tm_year=-1901,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=16,
+ .tm_min=26,
+ .tm_sec=8,
+ .tm_wday=5,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=-27232,
+ .tm_zone="LMT"
+ },
+ .gmt_tm= {
+ .tm_year=-1900,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=6,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="0000",
+ .timezone="right/UTC",
+ .time=-62167219200,
+ .local_tm= {
+ .tm_year=-1900,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=6,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=-1900,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=6,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="0000",
+ .timezone="right/America/Edmonton",
+ .time=-62167219200,
+ .local_tm= {
+ .tm_year=-1901,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=16,
+ .tm_min=26,
+ .tm_sec=8,
+ .tm_wday=5,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=-27232,
+ .tm_zone="LMT"
+ },
+ .gmt_tm= {
+ .tm_year=-1900,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=6,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="9999",
+ .timezone="posix/America/Edmonton",
+ .time=253402300799,
+ .local_tm= {
+ .tm_year=8099,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=16,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=5,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=8099,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=5,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="9999",
+ .timezone="right/UTC",
+ .time=253402300799,
+ .local_tm= {
+ .tm_year=8099,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=32,
+ .tm_wday=5,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=8099,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=5,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="9999",
+ .timezone="right/America/Edmonton",
+ .time=253402300799,
+ .local_tm= {
+ .tm_year=8099,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=16,
+ .tm_min=59,
+ .tm_sec=32,
+ .tm_wday=5,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=8099,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=5,
+ .tm_yday=364,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second - 1",
+ .timezone="posix/America/Edmonton",
+ .time=1483228825,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=17,
+ .tm_min=0,
+ .tm_sec=25,
+ .tm_wday=6,
+ .tm_yday=365,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=25,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second",
+ .timezone="posix/America/Edmonton",
+ .time=1483228826,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=17,
+ .tm_min=0,
+ .tm_sec=26,
+ .tm_wday=6,
+ .tm_yday=365,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=26,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second + 1",
+ .timezone="posix/America/Edmonton",
+ .time=1483228827,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=17,
+ .tm_min=0,
+ .tm_sec=27,
+ .tm_wday=6,
+ .tm_yday=365,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=27,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second - 1",
+ .timezone="right/UTC",
+ .time=1483228825,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=6,
+ .tm_yday=365,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=25,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second",
+ .timezone="right/UTC",
+ .time=1483228826,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=23,
+ .tm_min=59,
+ .tm_sec=60,
+ .tm_wday=6,
+ .tm_yday=365,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=26,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second + 1",
+ .timezone="right/UTC",
+ .time=1483228827,
+ .local_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="UTC"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=27,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second - 1",
+ .timezone="right/America/Edmonton",
+ .time=1483228825,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=16,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=6,
+ .tm_yday=365,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=25,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second",
+ .timezone="right/America/Edmonton",
+ .time=1483228826,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=16,
+ .tm_min=59,
+ .tm_sec=60,
+ .tm_wday=6,
+ .tm_yday=365,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=26,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="leap second + 1",
+ .timezone="right/America/Edmonton",
+ .time=1483228827,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=11,
+ .tm_mday=31,
+ .tm_hour=17,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=6,
+ .tm_yday=365,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=117,
+ .tm_mon=0,
+ .tm_mday=1,
+ .tm_hour=0,
+ .tm_min=0,
+ .tm_sec=27,
+ .tm_wday=0,
+ .tm_yday=0,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition standard to daylight - 1",
+ .timezone="posix/America/Edmonton",
+ .time=1457859599,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=1,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=8,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition standard to daylight",
+ .timezone="posix/America/Edmonton",
+ .time=1457859600,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=3,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=1,
+ .tm_gmtoff=-21600,
+ .tm_zone="MDT"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=9,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition standard to daylight + 1",
+ .timezone="posix/America/Edmonton",
+ .time=1457859601,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=3,
+ .tm_min=0,
+ .tm_sec=1,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=1,
+ .tm_gmtoff=-21600,
+ .tm_zone="MDT"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=9,
+ .tm_min=0,
+ .tm_sec=1,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition standard to daylight - 1",
+ .timezone="right/America/Edmonton",
+ .time=1457859625,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=1,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=9,
+ .tm_min=0,
+ .tm_sec=25,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition standard to daylight",
+ .timezone="right/America/Edmonton",
+ .time=1457859626,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=3,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=1,
+ .tm_gmtoff=-21600,
+ .tm_zone="MDT"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=9,
+ .tm_min=0,
+ .tm_sec=26,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition standard to daylight + 1",
+ .timezone="right/America/Edmonton",
+ .time=1457859627,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=3,
+ .tm_min=0,
+ .tm_sec=1,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=1,
+ .tm_gmtoff=-21600,
+ .tm_zone="MDT"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=2,
+ .tm_mday=13,
+ .tm_hour=9,
+ .tm_min=0,
+ .tm_sec=27,
+ .tm_wday=0,
+ .tm_yday=72,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition daylight to standard - 1",
+ .timezone="posix/America/Edmonton",
+ .time=1478419199,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=1,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=1,
+ .tm_gmtoff=-21600,
+ .tm_zone="MDT"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=7,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition daylight to standard",
+ .timezone="posix/America/Edmonton",
+ .time=1478419200,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=1,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=8,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition daylight to standard + 1",
+ .timezone="posix/America/Edmonton",
+ .time=1478419201,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=1,
+ .tm_min=0,
+ .tm_sec=1,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=8,
+ .tm_min=0,
+ .tm_sec=1,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition daylight to standard - 1",
+ .timezone="right/America/Edmonton",
+ .time=1478419225,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=1,
+ .tm_min=59,
+ .tm_sec=59,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=1,
+ .tm_gmtoff=-21600,
+ .tm_zone="MDT"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=8,
+ .tm_min=0,
+ .tm_sec=25,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition daylight to standard",
+ .timezone="right/America/Edmonton",
+ .time=1478419226,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=1,
+ .tm_min=0,
+ .tm_sec=0,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=8,
+ .tm_min=0,
+ .tm_sec=26,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr="transition daylight to standard + 1",
+ .timezone="right/America/Edmonton",
+ .time=1478419227,
+ .local_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=1,
+ .tm_min=0,
+ .tm_sec=1,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=-25200,
+ .tm_zone="MST"
+ },
+ .gmt_tm= {
+ .tm_year=116,
+ .tm_mon=10,
+ .tm_mday=6,
+ .tm_hour=8,
+ .tm_min=0,
+ .tm_sec=27,
+ .tm_wday=0,
+ .tm_yday=310,
+ .tm_isdst=0,
+ .tm_gmtoff=0,
+ .tm_zone="GMT"
+ },
+ },
+ {
+ .descr = NULL,
+ },
+};
+
+void printtm(FILE *f, struct tm *tm)
+{
+ fprintf(f, "\t\t{\n\t\t\t.tm_year=%d,\n\t\t\t.tm_mon=%d,\n\t\t\t"
+ ".tm_mday=%d,\n\t\t\t.tm_hour=%d,\n\t\t\t.tm_min=%d,\n\t\t\t"
+ ".tm_sec=%d,\n\t\t\t.tm_wday=%d,\n\t\t\t.tm_yday=%d,\n\t\t\t"
+ ".tm_isdst=%d,\n\t\t\t.tm_gmtoff=%ld,\n\t\t\t.tm_zone=\"%s\""
+ "\n\t\t},\n",
+ tm->tm_year,
+ tm->tm_mon,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ tm->tm_wday,
+ tm->tm_yday,
+ tm->tm_isdst,
+ tm->tm_gmtoff,
+ tm->tm_zone);
+}
+
+int dotimetest(struct timetest *test, int print)
+{
+ int failures = 0;
+ struct tm local = {}, gmt = {};
+ time_t converted;
+ if (gmtime_r(&test->time, &gmt) == NULL) {
+ memset(&gmt, 0, sizeof(gmt));
+ gmt.tm_zone="FAILURE";
+ } else {
+ converted = timegm(&gmt);
+ if (converted != test->time) {
+ fprintf(stderr, "FAIL: test \"%s\", tz \"%s\" timegm "
+ "does not match expected value\n", test->descr,
+ test->timezone);
+ fprintf(stderr, "expected: %lld\n", test->time);
+ fprintf(stderr, "actual: %lld\n", converted);
+ failures++;
+ }
+ }
+ if (!tm_match(&test->gmt_tm, &gmt)) {
+ fprintf(stderr, "FAIL: test \"%s\", tz \"%s\" gmtime_r does not"
+ " match expected value\n", test->descr, test->timezone);
+ fprintf(stderr, "expected: ");
+ printtm(stderr, &test->gmt_tm);
+ fprintf(stderr, "actual: ");
+ printtm(stderr, &gmt);
+ failures++;
+ }
+ setenv("TZ", test->timezone, 1);
+ if (localtime_r(&test->time, &local) == NULL) {
+ memset(&local, 0, sizeof(local));
+ local.tm_zone="FAILURE";
+ } else {
+ converted = mktime(&local);
+ if (converted != test->time) {
+ fprintf(stderr, "FAIL: test \"%s\", tz \"%s\" mktime "
+ "does not match expected value\n", test->descr,
+ test->timezone);
+ fprintf(stderr, "expected: %lld\n", test->time);
+ fprintf(stderr, "actual: %lld\n", converted);
+ failures++;
+ }
+ }
+ if (!tm_match(&test->local_tm, &local)) {
+ fprintf(stderr, "FAIL: test \"%s\", tz \"%s\" localtime_r does "
+ "not match expected value\n", test->descr, test->timezone);
+ fprintf(stderr, "expected: ");
+ printtm(stderr, &test->local_tm);
+ fprintf(stderr, "actual: ");
+ printtm(stderr, &local);
+ failures++;
+ }
+ if (print) {
+ printf("\t{\n\t\t.descr=\"%s\",\n\t\t.timezone=\"%s\",\n\t\t"
+ ".time=%lld,\n", test->descr, test->timezone, test->time);
+ printf("\t\t.local_tm=");
+ printtm(stdout, &local);
+ printf("\t\t.gmt_tm=");
+ printtm(stdout, &gmt);
+ printf("\t},\n");
+ }
+ return failures;
+}
+
+
+void printtmdescr(FILE *f, struct tm *tm, char * descr)
+{
+ fprintf(f, "%s: ", descr);
+ printtm(f, tm);
+}
+
+int main() {
+ int failures = 0;
+ int verbose = 0;
+ struct stat sb;
+
+ if (stat("/usr/share/zoneinfo/posix", &sb) == -1) {
+ fprintf(stderr, "WARNING: /usr/share/zoneinfo/posix not"
+ "present,\nCreate posix time zones to run this test.\n");
+ exit(0);
+ }
+ if (stat("/usr/share/zoneinfo/right", &sb) == -1) {
+ fprintf(stderr, "WARNING: /usr/share/zoneinfo/right not"
+ "present,\nCreate right time zones to run this test.\n");
+ exit(0);
+ }
+
+ for (size_t i = 0; timetests[i].descr != NULL; i++) {
+ failures += dotimetest(&timetests[i], verbose);
+ }
+ if (failures)
+ fprintf(stderr, "FAIL: %d time test failures\n", failures);
+ else
+ printf("SUCCESS: no time test failures\n");
+ exit(failures);
+}
+