xref: /illumos-gate/usr/src/test/tz-tests/tests/strftime_18091.c (revision 83cfce2593d5879e6831dd040afbd71e613d50f5)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2026 Oxide Computer Company
14  */
15 
16 /*
17  * Regression test for illumos#18091 where the current time has different time
18  * zone names than a past or future time. Prior to this test strftime would
19  * report time zone names based on the current time.
20  */
21 
22 #include <err.h>
23 #include <stdlib.h>
24 #include <time.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <sys/sysmacros.h>
28 
29 typedef struct st_test {
30 	const char *st_tz;
31 	long st_time;
32 	const char *st_exp;
33 } st_test_t;
34 
35 const st_test_t st_tests[] = { {
36 	/*
37 	 * America/Vancouver moved to MST in tzdata2026b. However, at the time,
38 	 * the current information would have had it in PST/PDT.
39 	 */
40 	.st_tz = "America/Vancouver",
41 	.st_time = 1798790400,
42 	.st_exp = "MST"
43 }, {
44 	.st_tz = "America/Vancouver",
45 	.st_time = 1777569072,
46 	.st_exp = "PDT"
47 }, {
48 	/*
49 	 * The other way this was originally reported.
50 	 */
51 	.st_tz = "Europe/Kyiv",
52 	.st_time = 500000000,
53 	.st_exp = "MSK"
54 }, {
55 	.st_tz = "Europe/Kyiv",
56 	.st_time = 700000000,
57 	.st_exp = "EET"
58 } };
59 
60 static bool
st_test_one(const st_test_t * test)61 st_test_one(const st_test_t *test)
62 {
63 	struct tm *tm;
64 	char buf[32];
65 
66 	(void) setenv("TZ", test->st_tz, 1);
67 	tm = localtime(&test->st_time);
68 	if (tm == NULL) {
69 		warn("TEST FAILED: %s (%ld): failed to convert to struct tm",
70 		    test->st_tz, test->st_time);
71 		return (false);
72 	}
73 
74 	if (strftime(buf, sizeof (buf), "%Z", tm) == 0) {
75 		warnx("TEST FAILED: %s (%ld): strftime wrote no data",
76 		    test->st_tz, test->st_time);
77 		return (false);
78 	}
79 
80 	if (strcmp(buf, test->st_exp) != 0) {
81 		warnx("TEST FAILED: %s (%ld): tz mismatch: found %s, expected "
82 		    "%s", test->st_tz, test->st_time, buf, test->st_exp);
83 		return (false);
84 	}
85 
86 	return (true);
87 }
88 
89 int
main(void)90 main(void)
91 {
92 	int ret = EXIT_SUCCESS;
93 
94 	for (size_t i = 0; i < ARRAY_SIZE(st_tests); i++) {
95 		if (!st_test_one(&st_tests[i]))
96 			ret = EXIT_FAILURE;
97 	}
98 
99 	if (ret == EXIT_SUCCESS) {
100 		(void) printf("All tests passed successfully!\n");
101 	}
102 	return (ret);
103 }
104