maint.mk: Update system header list for #include syntax checks.
[gnulib.git] / tests / test-localtime_r.c
blob5d4f02f00f73a5745fd4ba15df006f78a064f115
1 /* Test localtime_r().
2 Copyright (C) 2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2024. */
19 #include <config.h>
21 /* Specification. */
22 #include <time.h>
24 #include <string.h>
26 #include "macros.h"
29 /* Some common time zone name. */
31 #if defined _WIN32 && !defined __CYGWIN__
32 /* Cf. <https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones>
33 or <https://ss64.com/timezones.html> */
34 # define FRENCH_TZ "Romance Standard Time"
35 #else
36 /* Cf. <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones> */
37 # define FRENCH_TZ "Europe/Paris"
38 #endif
41 int
42 main (void)
44 setenv ("TZ", FRENCH_TZ, 1);
46 /* Check that this TZ works. */
48 time_t t = 0; /* 1970-01-01 01:00:00 */
49 struct tm *result = localtime (&t);
50 if (! (result
51 && result->tm_sec == 0
52 && result->tm_min == 0
53 && result->tm_hour == 1
54 && result->tm_mday == 1
55 && result->tm_mon == 1 - 1
56 && result->tm_year == 1970 - 1900
57 && result->tm_wday == 4
58 && result->tm_yday == 0
59 && result->tm_isdst == 0))
61 fputs ("Skipping test: TZ='" FRENCH_TZ "' is not Paris time\n",
62 stderr);
63 return 77;
67 /* Note: The result->tm_gmtoff values and the result->tm_zone values are the
68 same (3600, "CET" or 7200, "CEST") across all tested platforms:
69 glibc, musl, macOS, FreeBSD, NetBSD, OpenBSD, Minix, Cygwin, Android. */
71 /* A time point when DST was in effect. */
73 time_t t = 1178467200; /* 2007-05-06 18:00:00 */
74 struct tm tm;
75 struct tm *result = localtime_r (&t, &tm);
76 ASSERT (result == &tm);
77 ASSERT (result->tm_sec == 0);
78 ASSERT (result->tm_min == 0);
79 ASSERT (result->tm_hour == 18);
80 ASSERT (result->tm_mday == 6);
81 ASSERT (result->tm_mon == 5 - 1);
82 ASSERT (result->tm_year == 2007 - 1900);
83 ASSERT (result->tm_wday == 0);
84 ASSERT (result->tm_yday == 125);
85 ASSERT (result->tm_isdst == 1);
86 #if HAVE_STRUCT_TM_TM_GMTOFF
87 ASSERT (result->tm_gmtoff == (1 + result->tm_isdst) * 3600);
88 #endif
89 #if HAVE_STRUCT_TM_TM_ZONE
90 printf ("tm_zone = %s\n", result->tm_zone == NULL ? "(null)" : result->tm_zone);
91 ASSERT (strcmp (result->tm_zone, "CEST") == 0);
92 #endif
95 /* 1 second before and 1 second after the DST interval started. */
97 time_t t = 1174784399; /* 2007-03-25 01:59:59 */
98 struct tm tm;
99 struct tm *result = localtime_r (&t, &tm);
100 ASSERT (result == &tm);
101 ASSERT (result->tm_sec == 59);
102 ASSERT (result->tm_min == 59);
103 ASSERT (result->tm_hour == 1);
104 ASSERT (result->tm_mday == 25);
105 ASSERT (result->tm_mon == 3 - 1);
106 ASSERT (result->tm_year == 2007 - 1900);
107 ASSERT (result->tm_wday == 0);
108 ASSERT (result->tm_yday == 83);
109 ASSERT (result->tm_isdst == 0);
110 #if HAVE_STRUCT_TM_TM_GMTOFF
111 ASSERT (result->tm_gmtoff == (1 + result->tm_isdst) * 3600);
112 #endif
113 #if HAVE_STRUCT_TM_TM_ZONE
114 printf ("tm_zone = %s\n", result->tm_zone == NULL ? "(null)" : result->tm_zone);
115 ASSERT (strcmp (result->tm_zone, "CET") == 0);
116 #endif
119 time_t t = 1174784401; /* 2007-03-25 03:00:01 */
120 struct tm tm;
121 struct tm *result = localtime_r (&t, &tm);
122 ASSERT (result == &tm);
123 ASSERT (result->tm_sec == 1);
124 ASSERT (result->tm_min == 0);
125 ASSERT (result->tm_hour == 3);
126 ASSERT (result->tm_mday == 25);
127 ASSERT (result->tm_mon == 3 - 1);
128 ASSERT (result->tm_year == 2007 - 1900);
129 ASSERT (result->tm_wday == 0);
130 ASSERT (result->tm_yday == 83);
131 ASSERT (result->tm_isdst == 1);
132 #if HAVE_STRUCT_TM_TM_GMTOFF
133 ASSERT (result->tm_gmtoff == (1 + result->tm_isdst) * 3600);
134 #endif
135 #if HAVE_STRUCT_TM_TM_ZONE
136 printf ("tm_zone = %s\n", result->tm_zone == NULL ? "(null)" : result->tm_zone);
137 ASSERT (strcmp (result->tm_zone, "CEST") == 0);
138 #endif
141 /* 1 second before and 1 second after the DST interval ended. */
143 time_t t = 1193533199; /* 2007-10-28 02:59:59 */
144 struct tm tm;
145 struct tm *result = localtime_r (&t, &tm);
146 ASSERT (result == &tm);
147 ASSERT (result->tm_sec == 59);
148 ASSERT (result->tm_min == 59);
149 ASSERT (result->tm_hour == 2);
150 ASSERT (result->tm_mday == 28);
151 ASSERT (result->tm_mon == 10 - 1);
152 ASSERT (result->tm_year == 2007 - 1900);
153 ASSERT (result->tm_wday == 0);
154 ASSERT (result->tm_yday == 300);
155 ASSERT (result->tm_isdst == 1);
156 #if HAVE_STRUCT_TM_TM_GMTOFF
157 ASSERT (result->tm_gmtoff == (1 + result->tm_isdst) * 3600);
158 #endif
159 #if HAVE_STRUCT_TM_TM_ZONE
160 printf ("tm_zone = %s\n", result->tm_zone == NULL ? "(null)" : result->tm_zone);
161 ASSERT (strcmp (result->tm_zone, "CEST") == 0);
162 #endif
165 time_t t = 1193533201; /* 2007-10-28 02:00:01 */
166 struct tm tm;
167 struct tm *result = localtime_r (&t, &tm);
168 ASSERT (result == &tm);
169 ASSERT (result->tm_sec == 1);
170 ASSERT (result->tm_min == 0);
171 ASSERT (result->tm_hour == 2);
172 ASSERT (result->tm_mday == 28);
173 ASSERT (result->tm_mon == 10 - 1);
174 ASSERT (result->tm_year == 2007 - 1900);
175 ASSERT (result->tm_wday == 0);
176 ASSERT (result->tm_yday == 300);
177 ASSERT (result->tm_isdst == 0);
178 #if HAVE_STRUCT_TM_TM_GMTOFF
179 ASSERT (result->tm_gmtoff == (1 + result->tm_isdst) * 3600);
180 #endif
181 #if HAVE_STRUCT_TM_TM_ZONE
182 printf ("tm_zone = %s\n", result->tm_zone == NULL ? "(null)" : result->tm_zone);
183 ASSERT (strcmp (result->tm_zone, "CET") == 0);
184 #endif
187 return test_exit_status;