1/*2output:3testing4test1:5 test 06 n=6:Friday7 test 18 n=7:January9 test 210 n=2:2011 test 312 n=8:01/01/2113 test 414 n=10:2021-01-0115 test 516 n=4:202017 test 618 n=2:1019 test 720 n=2:1021 test 822 n=2:3023 test 924 n=5:10:3025 test 1026 n=2:5927 test 1128 n=8:14:30:5929 test 1230 n=2:0031 test 1332 n=2:5333 test 1434 n=2:0035 test 1536 n=8:14:30:5937 test 1638 n=4:202139 test 1740 n=4:202141 test 1842 n=3:UTC43 test 1944 n=3:Fri45 test 2046 n=3:Jan47 test 2148 n=24:Fri Jan 1 10:30:59 202149 test 2250 n=2:0151 test 2352 n=2: 153 test 2454 n=2:2055 test 2556 n=3:Jan57 test 2658 n=3:00159 test 2760 n=2:0161 test 2862 n=1:6364 test 2965 n=2:AM66 test 3067 n=2:PM68 test 3169 n=1:%70 test 3271 n=11:02:30:59 PM72 test 3373 n=1:74 test 3475 n=1:576 test 3577 n=1:578 test 3679 n=8:01/01/2180 test 3781 n=2:2182 test 3883 n=5:+000084 test 3985 n=7:49 199786 test 4087 n=7:53 199888test2:89test3:90test4:91test5:92test6:93test7:94test8:95test9:96test10:97test11:98test12:99test13:100test14:101test15:102test16:103test17:104test18:105test18:106done107end:108*/109110#include <assert.h>111#include <stdio.h>112#include <stdlib.h>113#include <string.h>114#include <time.h>115116#define NELEM(x) (sizeof(x)/sizeof((x)[0]))117118struct test {119 struct tm tm;120 char *fmt;121} tests[] = {122 //sec, min,hour,mday,mon,year,wday,yday,isdst, fmt123 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%A"},124 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%B"},125 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%C"},126 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%D"},127 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%F"},128 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%G"},129 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%H"},130 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%I"},131 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%M"},132 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%R"},133 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%S"},134 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%T"},135 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%U"},136 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%V"},137 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%W"},138 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%X"},139 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%Y"},140 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%Y"},141 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%Z"},142 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%a"},143 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%b"},144 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%c"},145 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%d"},146 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%e"},147 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%g"},148 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%h"},149 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%j"},150 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%m"},151 {{0}, "%n"},152 {{ 59, 30, 10, 1, 0, 121, 5, 0}, "%p"},153 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%p"},154 {{0}, "%%"},155 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%r"},156 {{0}, "%t"},157 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%u"},158 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%w"},159 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%x"},160 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%y"},161 {{ 59, 30, 14, 1, 0, 121, 5, 0}, "%z"},162 {{ 59, 30, 10, 1, 11, 97, 2, 363}, "%V %G"},163 {{ 59, 30, 10, 2, 0, 99, 6, 1}, "%V %G"},164};165166#ifndef __unix__167#define putenv(x) (x)168/*169 * Ok, this is by definition undefined behaviour because170 * we are using the name of a library function. The reallity171 * is that if you use a static linker then this would172 * overload the libc getenv and it will work as expected,173 * but if you use a dynamic linker then the internal174 * references will be tied to the internal getenv function175 * and this would not work. For our main use case that is176 * testing scc libc this is good enough, and with the177 * fallback to putenv this will work in the systems we are178 * interested on179 */180char *181getenv(const char *name)182{183 if (strcmp(name, "TZ") != 0)184 return NULL;185 return "UTC";186}187#endif188189void190test1(void)191{192 int n;193 char buf[70];194 struct test *tp;195196 puts("test1:");197 for (tp = tests; tp < &tests[NELEM(tests)]; ++tp) {198 printf("\ttest %d\n", (int) (tp - tests));199 mktime(&tp->tm);200 n = strftime(buf, sizeof(buf), tp->fmt, &tp->tm);201 printf("\t\tn=%d:%s\n", n, buf);202 }203}204205void206test2(void)207{208 struct tm tm;209 char s1[32], s2[32];210 size_t n1, n2;211212 puts("test2:");213 tm.tm_sec = 59;214 tm.tm_min = 30;215 tm.tm_hour = 10;216 tm.tm_mday = 1;217 tm.tm_mon = 0;218 tm.tm_year = 121;219 tm.tm_wday = 5;220 tm.tm_yday = 0;221222 n1 = strftime(s1, 32, "%c", &tm);223 n2 = strftime(s2, 32, "%Ec", &tm);224225 assert(n1 == 24 && strcmp(s1, "Fri Jan 1 10:30:59 2021") == 0);226 assert(n2 == 24 && strcmp(s2, "Fri Jan 1 10:30:59 2021") == 0);227}228229void230test3(void)231{232 struct tm tm;233 char s1[8], s2[8];234 size_t n1, n2;235236 puts("test3:");237 tm.tm_sec = 59;238 tm.tm_min = 30;239 tm.tm_hour = 10;240 tm.tm_mday = 1;241 tm.tm_mon = 0;242 tm.tm_year = 121;243 tm.tm_wday = 5;244 tm.tm_yday = 0;245246 n1 = strftime(s1, 8, "%d", &tm);247 n2 = strftime(s2, 8, "%Od", &tm);248249 assert(n1 == 2 && strcmp(s1, "01") == 0);250 assert(n2 == 2 && strcmp(s2, "01") == 0);251}252253void254test4(void)255{256 struct tm tm;257 char s1[8], s2[8];258 size_t n1, n2;259260 puts("test4:");261 tm.tm_sec = 59;262 tm.tm_min = 30;263 tm.tm_hour = 10;264 tm.tm_mday = 1;265 tm.tm_mon = 0;266 tm.tm_year = 121;267 tm.tm_wday = 5;268 tm.tm_yday = 0;269270 n1 = strftime(s1, 8, "%e", &tm);271 n2 = strftime(s2, 8, "%Oe", &tm);272273 assert(n1 == 2 && strcmp(s1, " 1") == 0);274 assert(n2 == 2 && strcmp(s2, " 1") == 0);275}276277void278test5(void)279{280 struct tm tm;281 char s1[8], s2[8];282 size_t n1, n2;283284 puts("test5:");285 tm.tm_sec = 59;286 tm.tm_min = 30;287 tm.tm_hour = 14;288 tm.tm_mday = 1;289 tm.tm_mon = 0;290 tm.tm_year = 121;291 tm.tm_wday = 5;292 tm.tm_yday = 0;293294 n1 = strftime(s1, 8, "%m", &tm);295 n2 = strftime(s2, 8, "%Om", &tm);296297 assert(n1 == 2 && strcmp(s1, "01") == 0);298 assert(n2 == 2 && strcmp(s2, "01") == 0);299}300301void302test6(void)303{304 struct tm tm;305 char s1[8], s2[8];306 size_t n1, n2;307308 puts("test6:");309 tm.tm_sec = 59;310 tm.tm_min = 30;311 tm.tm_hour = 14;312 tm.tm_mday = 1;313 tm.tm_mon = 0;314 tm.tm_year = 121;315 tm.tm_wday = 5;316 tm.tm_yday = 0;317318 n1 = strftime(s1, 8, "%u", &tm);319 n2 = strftime(s2, 8, "%Ou", &tm);320321 assert(n1 == 1 && strcmp(s1, "5") == 0);322 assert(n2 == 1 && strcmp(s2, "5") == 0);323}324325void326test7(void)327{328 struct tm tm;329 char s1[8], s2[8];330 size_t n1, n2;331332 puts("test7:");333 tm.tm_sec = 59;334 tm.tm_min = 30;335 tm.tm_hour = 14;336 tm.tm_mday = 1;337 tm.tm_mon = 0;338 tm.tm_year = 121;339 tm.tm_wday = 5;340 tm.tm_yday = 0;341342 n1 = strftime(s1, 8, "%w", &tm);343 n2 = strftime(s2, 8, "%Ow", &tm);344345 assert(n1 == 1 && strcmp(s1, "5") == 0);346 assert(n2 == 1 && strcmp(s2, "5") == 0);347}348349void350test8(void)351{352 struct tm tm;353 char s1[16], s2[16];354 size_t n1, n2;355356 puts("test8:");357 tm.tm_sec = 59;358 tm.tm_min = 30;359 tm.tm_hour = 14;360 tm.tm_mday = 1;361 tm.tm_mon = 0;362 tm.tm_year = 121;363 tm.tm_wday = 5;364 tm.tm_yday = 0;365366 n1 = strftime(s1, 16, "%x", &tm);367 n2 = strftime(s2, 16, "%Ex", &tm);368369 assert(n1 == 8 && strcmp(s1, "01/01/21") == 0);370 assert(n2 == 8 && strcmp(s2, "01/01/21") == 0);371}372373void374test9(void)375{376 struct tm tm;377 char s1[8], s2[8], s3[8];378 size_t n1, n2, n3;379380 puts("test9:");381 tm.tm_sec = 59;382 tm.tm_min = 30;383 tm.tm_hour = 14;384 tm.tm_mday = 1;385 tm.tm_mon = 0;386 tm.tm_year = 121;387 tm.tm_wday = 5;388 tm.tm_yday = 0;389390 n1 = strftime(s1, 8, "%y", &tm);391 n2 = strftime(s2, 8, "%Ey", &tm);392 n3 = strftime(s3, 8, "%Oy", &tm);393394 assert(n1 == 2 && strcmp(s1, "21") == 0);395 assert(n2 == 2 && strcmp(s2, "21") == 0);396 assert(n3 == 2 && strcmp(s3, "21") == 0);397}398399void400test10(void)401{402 struct tm tm;403 char s1[8], s2[8];404 size_t n1, n2;405406 puts("test10:");407 tm.tm_sec = 59;408 tm.tm_min = 30;409 tm.tm_hour = 10;410 tm.tm_mday = 1;411 tm.tm_mon = 0;412 tm.tm_year = 121;413 tm.tm_wday = 5;414 tm.tm_yday = 0;415416 n1 = strftime(s1, 8, "%C", &tm);417 n2 = strftime(s2, 8, "%EC", &tm);418419 assert(n1 == 2 && strcmp(s1, "20") == 0);420 assert(n2 == 2 && strcmp(s2, "20") == 0);421}422423void424test11(void)425{426 struct tm tm;427 char s1[8], s2[8];428 size_t n1, n2;429430 puts("test11:");431 tm.tm_sec = 59;432 tm.tm_min = 30;433 tm.tm_hour = 14;434 tm.tm_mday = 1;435 tm.tm_mon = 0;436 tm.tm_year = 121;437 tm.tm_wday = 5;438 tm.tm_yday = 0;439440 n1 = strftime(s1, 8, "%H", &tm);441 n2 = strftime(s2, 8, "%OH", &tm);442443 assert(n1 == 2 && strcmp(s1, "14") == 0);444 assert(n2 == 2 && strcmp(s2, "14") == 0);445}446447void448test12(void)449{450 struct tm tm;451 char s1[8], s2[8];452 size_t n1, n2;453454 puts("test12:");455 tm.tm_sec = 59;456 tm.tm_min = 30;457 tm.tm_hour = 14;458 tm.tm_mday = 1;459 tm.tm_mon = 0;460 tm.tm_year = 121;461 tm.tm_wday = 5;462 tm.tm_yday = 0;463464 n1 = strftime(&s1[0], 8, "%I", &tm);465 n2 = strftime(&s2[0], 8, "%OI", &tm);466467 assert(n1 == 2 && strcmp(s1, "02") == 0);468 assert(n2 == 2 && strcmp(s2, "02") == 0);469}470471void472test13(void)473{474 struct tm tm;475 char s1[8], s2[8];476 size_t n1, n2;477478 puts("test13:");479 tm.tm_sec = 59;480 tm.tm_min = 30;481 tm.tm_hour = 14;482 tm.tm_mday = 1;483 tm.tm_mon = 0;484 tm.tm_year = 121;485 tm.tm_wday = 5;486 tm.tm_yday = 0;487488 n1 = strftime(s1, 8, "%M", &tm);489 n2 = strftime(s2, 8, "%OM", &tm);490491 assert(n1 == 2 && strcmp(s1, "30") == 0);492 assert(n2 == 2 && strcmp(s2, "30") == 0);493}494495void496test14(void)497{498 struct tm tm;499 char s1[8], s2[8];500 size_t n1, n2;501502 puts("test14:");503 tm.tm_sec = 59;504 tm.tm_min = 30;505 tm.tm_hour = 14;506 tm.tm_mday = 1;507 tm.tm_mon = 0;508 tm.tm_year = 121;509 tm.tm_wday = 5;510 tm.tm_yday = 0;511512 n1 = strftime(s1, 8, "%S", &tm);513 n2 = strftime(s2, 8, "%OS", &tm);514515 assert(n1 == 2 && strcmp(s1, "59") == 0);516 assert(n2 == 2 && strcmp(s2, "59") == 0);517}518519void520test15(void)521{522 struct tm tm;523 char s1[8], s2[8];524 size_t n1, n2;525526 puts("test15:");527 tm.tm_sec = 59;528 tm.tm_min = 30;529 tm.tm_hour = 14;530 tm.tm_mday = 1;531 tm.tm_mon = 0;532 tm.tm_year = 121;533 tm.tm_wday = 5;534 tm.tm_yday = 0;535536 n1 = strftime(s1, 8, "%U", &tm);537 n2 = strftime(s2, 8, "%OU", &tm);538539 assert(n1 == 2 && strcmp(s1, "00") == 0);540 assert(n2 == 2 && strcmp(s2, "00") == 0);541}542543void544test16(void)545{546 struct tm tm;547 char s1[8], s2[8];548 size_t n1, n2;549550 puts("test16:");551 tm.tm_sec = 59;552 tm.tm_min = 30;553 tm.tm_hour = 14;554 tm.tm_mday = 1;555 tm.tm_mon = 0;556 tm.tm_year = 121;557 tm.tm_wday = 5;558 tm.tm_yday = 0;559560 n1 = strftime(s1, 8, "%V", &tm);561 n2 = strftime(s2, 8, "%OV", &tm);562563 assert(n1 == 2 && strcmp(s1, "53") == 0);564 assert(n2 == 2 && strcmp(s2, "53") == 0);565}566567void568test17(void)569{570 struct tm tm;571 char s1[8], s2[8];572 size_t n1, n2;573574 puts("test17:");575 tm.tm_sec = 59;576 tm.tm_min = 30;577 tm.tm_hour = 14;578 tm.tm_mday = 1;579 tm.tm_mon = 0;580 tm.tm_year = 121;581 tm.tm_wday = 5;582 tm.tm_yday = 0;583584 n1 = strftime(s1, 8, "%W", &tm);585 n2 = strftime(s2, 8, "%OW", &tm);586587 assert(n1 == 2 && strcmp(s1, "00") == 0);588 assert(n2 == 2 && strcmp(s2, "00") == 0);589590}591592void593test18(void)594{595 struct tm tm;596 char s1[16], s2[16];597 size_t n1, n2;598599 puts("test18:");600 tm.tm_sec = 59;601 tm.tm_min = 30;602 tm.tm_hour = 14;603 tm.tm_mday = 1;604 tm.tm_mon = 0;605 tm.tm_year = 121;606 tm.tm_wday = 5;607 tm.tm_yday = 0;608609 n1 = strftime(&s1[0], 16, "%X", &tm);610 n2 = strftime(&s2[0], 16, "%EX", &tm);611612 assert(n1 == 8 && strcmp(s1, "14:30:59") == 0);613 assert(n2 == 8 && strcmp(s2, "14:30:59") == 0);614}615616void617test19(void)618{619 struct tm tm;620 char s1[8], s2[8];621 size_t n1, n2;622623 puts("test18:");624 tm.tm_sec = 59;625 tm.tm_min = 30;626 tm.tm_hour = 14;627 tm.tm_mday = 1;628 tm.tm_mon = 0;629 tm.tm_year = 121;630 tm.tm_wday = 5;631 tm.tm_yday = 0;632633 n1 = strftime(s1, 8, "%Y", &tm);634 n2 = strftime(s2, 8, "%EY", &tm);635636 assert(n1 == 4 && strcmp(s1, "2021") == 0);637 assert(n2 == 4 && strcmp(s2, "2021") == 0);638}639640int641main(void)642{643 puts("testing");644 putenv("TZ=UTC");645 test1();646 test2();647 test3();648 test4();649 test5();650 test6();651 test7();652 test8();653 test9();654 test10();655 test11();656 test12();657 test13();658 test14();659 test15();660 test16();661 test17();662 test18();663 test19();664 puts("done");665666 return 0;667}