1/*2output:3testing4test 05tm_sec= 0, tm_min= 3, tm_hour= 0, tm_mday= 1, tm_mon= 0, tm_year= 121, tm_wday=5, tm_yday= 0, tm_isdst=06Fri Jan 1 00:03:00 2021 UTC7Fri Jan 1 00:03:00 2021 UTC8Fri Jan 1 00:03:00 2021 UTC9Fri Jan 1 00:03:00 202110Fri Jan 1 00:03:00 202111test 112tm_sec=50, tm_min=30, tm_hour=23, tm_mday=31, tm_mon=11, tm_year= 120, tm_wday=4, tm_yday=365, tm_isdst=013Thu Dec 31 23:30:50 2020 UTC14Thu Dec 31 23:30:50 2020 UTC15Thu Dec 31 23:30:50 2020 UTC16Thu Dec 31 23:30:50 202017Thu Dec 31 23:30:50 202018test 219tm_sec=59, tm_min=30, tm_hour= 0, tm_mday= 1, tm_mon= 0, tm_year= 121, tm_wday=5, tm_yday= 0, tm_isdst=020Fri Jan 1 00:30:59 2021 UTC21Fri Jan 1 00:30:59 2021 UTC22Fri Jan 1 00:30:59 2021 UTC23Fri Jan 1 00:30:59 202124Fri Jan 1 00:30:59 202125test 326tm_sec=59, tm_min=30, tm_hour=12, tm_mday=30, tm_mon=11, tm_year= 120, tm_wday=3, tm_yday=364, tm_isdst=027Wed Dec 30 12:30:59 2020 UTC28Wed Dec 30 12:30:59 2020 UTC29Wed Dec 30 12:30:59 2020 UTC30Wed Dec 30 12:30:59 202031Wed Dec 30 12:30:59 202032test 433tm_sec=59, tm_min=30, tm_hour=12, tm_mday= 1, tm_mon= 0, tm_year= 121, tm_wday=5, tm_yday= 0, tm_isdst=034Fri Jan 1 12:30:59 2021 UTC35Fri Jan 1 12:30:59 2021 UTC36Fri Jan 1 12:30:59 2021 UTC37Fri Jan 1 12:30:59 202138Fri Jan 1 12:30:59 202139test 540tm_sec=59, tm_min=59, tm_hour=23, tm_mday=31, tm_mon=11, tm_year= 120, tm_wday=4, tm_yday=365, tm_isdst=041Thu Dec 31 23:59:59 2020 UTC42Thu Dec 31 23:59:59 2020 UTC43Thu Dec 31 23:59:59 2020 UTC44Thu Dec 31 23:59:59 202045Thu Dec 31 23:59:59 202046test 647tm_sec= 0, tm_min= 3, tm_hour= 0, tm_mday= 1, tm_mon= 0, tm_year= 121, tm_wday=5, tm_yday= 0, tm_isdst=048Fri Jan 1 00:03:00 2021 UTC49Fri Jan 1 00:03:00 2021 UTC50Fri Jan 1 00:03:00 2021 UTC51Fri Jan 1 00:03:00 202152Fri Jan 1 00:03:00 202153test 754tm_sec=59, tm_min=30, tm_hour=12, tm_mday=30, tm_mon=11, tm_year= 120, tm_wday=3, tm_yday=364, tm_isdst=055Wed Dec 30 12:30:59 2020 UTC56Wed Dec 30 12:30:59 2020 UTC57Wed Dec 30 12:30:59 2020 UTC58Wed Dec 30 12:30:59 202059Wed Dec 30 12:30:59 202060test 861tm_sec=59, tm_min=30, tm_hour=12, tm_mday=20, tm_mon= 0, tm_year= 121, tm_wday=3, tm_yday= 19, tm_isdst=062Wed Jan 20 12:30:59 2021 UTC63Wed Jan 20 12:30:59 2021 UTC64Wed Jan 20 12:30:59 2021 UTC65Wed Jan 20 12:30:59 202166Wed Jan 20 12:30:59 202167test 968tm_sec=59, tm_min=59, tm_hour=23, tm_mday=31, tm_mon=11, tm_year= 120, tm_wday=4, tm_yday=365, tm_isdst=069Thu Dec 31 23:59:59 2020 UTC70Thu Dec 31 23:59:59 2020 UTC71Thu Dec 31 23:59:59 2020 UTC72Thu Dec 31 23:59:59 202073Thu Dec 31 23:59:59 202074test 1075tm_sec= 0, tm_min= 0, tm_hour= 0, tm_mday= 1, tm_mon= 0, tm_year= 121, tm_wday=5, tm_yday= 0, tm_isdst=076Fri Jan 1 00:00:00 2021 UTC77Fri Jan 1 00:00:00 2021 UTC78Fri Jan 1 00:00:00 2021 UTC79Fri Jan 1 00:00:00 202180Fri Jan 1 00:00:00 202181test 1182tm_sec=59, tm_min=38, tm_hour=12, tm_mday=10, tm_mon=11, tm_year= 33, tm_wday=0, tm_yday=343, tm_isdst=083Sun Dec 10 12:38:59 1933 UTC84Sun Dec 10 12:38:59 1933 UTC85Sun Dec 10 12:38:59 1933 UTC86Sun Dec 10 12:38:59 193387Sun Dec 10 12:38:59 193388test 1289tm_sec=59, tm_min=38, tm_hour=12, tm_mday=12, tm_mon=11, tm_year= 33, tm_wday=2, tm_yday=345, tm_isdst=090Tue Dec 12 12:38:59 1933 UTC91Tue Dec 12 12:38:59 1933 UTC92Tue Dec 12 12:38:59 1933 UTC93Tue Dec 12 12:38:59 193394Tue Dec 12 12:38:59 193395test 1396tm_wday=200, tm_yday=50097failed98test 1499tm_sec= 0, tm_min= 3, tm_hour= 0, tm_mday= 1, tm_mon= 0, tm_year= 121, tm_wday=5, tm_yday= 0, tm_isdst=0100Fri Jan 1 00:03:00 2021 UTC101Fri Jan 1 00:03:00 2021 UTC102Fri Jan 1 00:03:00 2021 UTC103Fri Jan 1 00:03:00 2021104Fri Jan 1 00:03:00 2021105test 15106tm_sec= 0, tm_min= 3, tm_hour= 0, tm_mday= 1, tm_mon= 0, tm_year= 121, tm_wday=5, tm_yday= 0, tm_isdst=0107Fri Jan 1 00:03:00 2021 UTC108Fri Jan 1 00:03:00 2021 UTC109Fri Jan 1 00:03:00 2021 UTC110Fri Jan 1 00:03:00 2021111Fri Jan 1 00:03:00 2021112test 16113tm_sec= 0, tm_min= 3, tm_hour= 0, tm_mday= 1, tm_mon= 0, tm_year= 121, tm_wday=5, tm_yday= 0, tm_isdst=0114Fri Jan 1 00:03:00 2021 UTC115Fri Jan 1 00:03:00 2021 UTC116Fri Jan 1 00:03:00 2021 UTC117Fri Jan 1 00:03:00 2021118Fri Jan 1 00:03:00 2021119done120end:121*/122123#include <limits.h>124#include <stdio.h>125#include <stdlib.h>126#include <string.h>127#include <time.h>128129#define NELEM(x) (sizeof(x)/sizeof((x)[0]))130131struct test {132 struct tm tm;133 int fail;134} tests[] = {135 //sec,min,hour,mday,mon,year,wday,yday,isdst,fail136 {{ 60, 62, 23, 31, 11, 120, 200, 500}},137 {{ 50, 30, -1, 1, 0, 121}},138 {{ 59, 30, 24, 31, 11, 120}},139 {{ 59, 30, 12, -1, 0, 121}},140 {{ 59, 30, 12, 32, 11, 120}},141 {{ 59, -1, 0, 1, 0, 121}},142 {{ 60, 62, 23, 31, 11, 120}},143 {{ 59, 30, 12, 30, -1, 121}},144 {{ 59, 30, 12, 20, 12, 120}},145 {{ -1, 0, 0, 1, 0, 121}},146 {{ 60, 59, 23, 31, 11, 120}},147 {{ 59, 38, 12, 10, 11, 33}},148 {{ 59, 38, 12, 12, 11, 33}},149 {{ 72, 38, 1, 31, 15,INT_MAX, 200, 500}, 1},150 {{ 60, 62, 23, 31, 11, 120, 0, 0, 1}},151 {{ 60, 62, 23, 31, 11, 120, 0, 0, 0}},152 {{ 60, 62, 23, 31, 11, 120, 0, 0, -1}},153};154155#ifndef __unix__156#define putenv(x) (x)157/*158 * Ok, this is by definition undefined behaviour because159 * we are using the name of a library function. The reallity160 * is that if you use a static linker then this would161 * overload the libc getenv and it will work as expected,162 * but if you use a dynamic linker then the internal163 * references will be tied to the internal getenv function164 * and this would not work. For our main use case that is165 * testing scc libc this is good enough, and with the166 * fallback to putenv this will work in the systems we are167 * interested on168 */169char *170getenv(const char *name)171{172 if (strcmp(name, "TZ") != 0)173 return NULL;174 return "UTC";175}176#endif177178int179main(void)180{181 time_t t;182 char buf[70];183 struct tm *tm;184 struct test *tp;185186 puts("testing");187 putenv("TZ=UTC");188 for (tp = tests; tp < &tests[NELEM(tests)]; ++tp) {189 printf("test %d\n", (int) (tp - tests));190 t = mktime(&tp->tm);191 if (tp->fail) {192 printf("tm_wday=%d, tm_yday=%d\n",193 tp->tm.tm_wday, tp->tm.tm_yday);194 puts(t == -1 ? "failed" : "not failed");195 continue;196 }197 printf("tm_sec=%2d, "198 "tm_min=%2d, "199 "tm_hour=%2d, "200 "tm_mday=%2d, "201 "tm_mon=%2d, "202 "tm_year=%4d, "203 "tm_wday=%d, "204 "tm_yday=%3d, "205 "tm_isdst=%d\n",206 tp->tm.tm_sec,207 tp->tm.tm_min,208 tp->tm.tm_hour,209 tp->tm.tm_mday,210 tp->tm.tm_mon,211 tp->tm.tm_year,212 tp->tm.tm_wday,213 tp->tm.tm_yday,214 tp->tm.tm_isdst);215 strftime(buf, sizeof(buf), "%c %Z", &tp->tm);216 puts(buf);217218 tm = gmtime(&t);219 strftime(buf, sizeof(buf), "%c %Z", tm);220 puts(buf);221222 tm = localtime(&t);223 strftime(buf, sizeof(buf), "%c %Z", tm);224 puts(buf);225226 fputs(asctime(tm), stdout);227 fputs(ctime(&t), stdout);228 }229 puts("done");230231 return 0;232}233