1 /* A more-standard <time.h>.
2
3 Copyright (C) 2007-2023 Free Software Foundation, Inc.
4
5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
9
10 This file is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17
18 #if __GNUC__ >= 3
19 @PRAGMA_SYSTEM_HEADER@
20 #endif
21 @PRAGMA_COLUMNS@
22
23 /* This file uses #include_next of a system file that defines time_t.
24 For the 'year2038' module to work right, <config.h> needs to have been
25 included before. */
26 #if !_GL_CONFIG_H_INCLUDED
27 #error "Please include config.h first."
28 #endif
29
30 /* Don't get in the way of glibc when it includes time.h merely to
31 declare a few standard symbols, rather than to declare all the
32 symbols. (However, skip this for MinGW as it treats __need_time_t
33 incompatibly.) Also, Solaris 8 <time.h> eventually includes itself
34 recursively; if that is happening, just include the system <time.h>
35 without adding our own declarations. */
36 #if (((defined __need_time_t || defined __need_clock_t \
37 || defined __need_timespec) \
38 && !defined __MINGW32__) \
39 || defined _@GUARD_PREFIX@_TIME_H)
40
41 # @INCLUDE_NEXT@ @NEXT_TIME_H@
42
43 #else
44
45 # define _@GUARD_PREFIX@_TIME_H
46
47 /* mingw's <time.h> provides the functions asctime_r, ctime_r, gmtime_r,
48 localtime_r only if <unistd.h> or <pthread.h> has been included before. */
49 # if defined __MINGW32__
50 # include <unistd.h>
51 # endif
52
53 # @INCLUDE_NEXT@ @NEXT_TIME_H@
54
55 /* This file uses _GL_ATTRIBUTE_DEPRECATED, GNULIB_POSIXCHECK,
56 HAVE_RAW_DECL_*. */
57 # if !_GL_CONFIG_H_INCLUDED
58 # error "Please include config.h first."
59 # endif
60
61 /* NetBSD 5.0 mis-defines NULL. */
62 # include <stddef.h>
63
64 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
65
66 /* The definition of _GL_ARG_NONNULL is copied here. */
67
68 /* The definition of _GL_WARN_ON_USE is copied here. */
69
70 /* Some systems don't define struct timespec (e.g., AIX 4.1).
71 Or they define it with the wrong member names or define it in <sys/time.h>
72 (e.g., FreeBSD circa 1997). Stock Mingw prior to 3.0 does not define it,
73 but the pthreads-win32 library defines it in <pthread.h>. */
74 # if ! @TIME_H_DEFINES_STRUCT_TIMESPEC@
75 # if @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
76 # include <sys/time.h>
77 # elif @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
78 # include <pthread.h>
79 # elif @UNISTD_H_DEFINES_STRUCT_TIMESPEC@
80 # include <unistd.h>
81 # else
82
83 # ifdef __cplusplus
84 extern "C" {
85 # endif
86
87 # if !GNULIB_defined_struct_timespec
88 # undef timespec
89 # define timespec rpl_timespec
90 struct timespec
91 {
92 time_t tv_sec;
93 long int tv_nsec;
94 };
95 # define GNULIB_defined_struct_timespec 1
96 # endif
97
98 # ifdef __cplusplus
99 }
100 # endif
101
102 # endif
103 # endif
104
105 # if !GNULIB_defined_struct_time_t_must_be_integral
106 /* https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html
107 requires time_t to be an integer type, even though C99 permits floating
108 point. We don't know of any implementation that uses floating
109 point, and it is much easier to write code that doesn't have to
110 worry about that corner case, so we force the issue. */
111 struct __time_t_must_be_integral {
112 unsigned int __floating_time_t_unsupported : (time_t) 1;
113 };
114 # define GNULIB_defined_struct_time_t_must_be_integral 1
115 # endif
116
117 /* Define TIME_UTC, a positive integer constant used for timespec_get(). */
118 # if ! @TIME_H_DEFINES_TIME_UTC@
119 # if !GNULIB_defined_TIME_UTC
120 # define TIME_UTC 1
121 # define GNULIB_defined_TIME_UTC 1
122 # endif
123 # endif
124
125 /* Set *TS to the current time, and return BASE.
126 Upon failure, return 0. */
127 # if @GNULIB_TIMESPEC_GET@
128 # if @REPLACE_TIMESPEC_GET@
129 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
130 # undef timespec_get
131 # define timespec_get rpl_timespec_get
132 # endif
133 _GL_FUNCDECL_RPL (timespec_get, int, (struct timespec *ts, int base)
134 _GL_ARG_NONNULL ((1)));
135 _GL_CXXALIAS_RPL (timespec_get, int, (struct timespec *ts, int base));
136 # else
137 # if !@HAVE_TIMESPEC_GET@
138 _GL_FUNCDECL_SYS (timespec_get, int, (struct timespec *ts, int base)
139 _GL_ARG_NONNULL ((1)));
140 # endif
141 _GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, int base));
142 # endif
143 # if __GLIBC__ >= 2
144 _GL_CXXALIASWARN (timespec_get);
145 # endif
146 # endif
147
148 /* Set *TS to the current time resolution, and return BASE.
149 Upon failure, return 0. */
150 # if @GNULIB_TIMESPEC_GETRES@
151 # if ! @HAVE_TIMESPEC_GETRES@
152 _GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec *ts, int base)
153 _GL_ARG_NONNULL ((1)));
154 # endif
155 _GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base));
156 _GL_CXXALIASWARN (timespec_getres);
157 # endif
158
159 /* Return the number of seconds that have elapsed since the Epoch. */
160 # if @GNULIB_TIME@
161 # if @REPLACE_TIME@
162 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
163 # define time rpl_time
164 # endif
165 _GL_FUNCDECL_RPL (time, time_t, (time_t *__tp));
166 _GL_CXXALIAS_RPL (time, time_t, (time_t *__tp));
167 # else
168 _GL_CXXALIAS_SYS (time, time_t, (time_t *__tp));
169 # endif
170 # if __GLIBC__ >= 2
171 _GL_CXXALIASWARN (time);
172 # endif
173 # endif
174
175 /* Sleep for at least RQTP seconds unless interrupted, If interrupted,
176 return -1 and store the remaining time into RMTP. See
177 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html>. */
178 # if @GNULIB_NANOSLEEP@
179 # if @REPLACE_NANOSLEEP@
180 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
181 # define nanosleep rpl_nanosleep
182 # endif
183 _GL_FUNCDECL_RPL (nanosleep, int,
184 (struct timespec const *__rqtp, struct timespec *__rmtp)
185 _GL_ARG_NONNULL ((1)));
186 _GL_CXXALIAS_RPL (nanosleep, int,
187 (struct timespec const *__rqtp, struct timespec *__rmtp));
188 # else
189 # if ! @HAVE_NANOSLEEP@
190 _GL_FUNCDECL_SYS (nanosleep, int,
191 (struct timespec const *__rqtp, struct timespec *__rmtp)
192 _GL_ARG_NONNULL ((1)));
193 # endif
194 _GL_CXXALIAS_SYS (nanosleep, int,
195 (struct timespec const *__rqtp, struct timespec *__rmtp));
196 # endif
197 _GL_CXXALIASWARN (nanosleep);
198 # endif
199
200 /* Initialize time conversion information. */
201 # if @GNULIB_TZSET@
202 # if @REPLACE_TZSET@
203 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
204 # undef tzset
205 # define tzset rpl_tzset
206 # endif
207 _GL_FUNCDECL_RPL (tzset, void, (void));
208 _GL_CXXALIAS_RPL (tzset, void, (void));
209 # elif defined _WIN32 && !defined __CYGWIN__
210 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
211 # undef tzset
212 # define tzset _tzset
213 # endif
214 _GL_CXXALIAS_MDA (tzset, void, (void));
215 # else
216 _GL_CXXALIAS_SYS (tzset, void, (void));
217 # endif
218 _GL_CXXALIASWARN (tzset);
219 # elif @GNULIB_MDA_TZSET@
220 /* On native Windows, map 'tzset' to '_tzset', so that -loldnames is not
221 required. In C++ with GNULIB_NAMESPACE, avoid differences between
222 platforms by defining GNULIB_NAMESPACE::tzset always. */
223 # if defined _WIN32 && !defined __CYGWIN__
224 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
225 # undef tzset
226 # define tzset _tzset
227 # endif
228 _GL_CXXALIAS_MDA (tzset, void, (void));
229 # else
230 _GL_CXXALIAS_SYS (tzset, void, (void));
231 # endif
232 _GL_CXXALIASWARN (tzset);
233 # endif
234
235 /* Return the 'time_t' representation of TP and normalize TP. */
236 # if @GNULIB_MKTIME@
237 # if @REPLACE_MKTIME@
238 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
239 # define mktime rpl_mktime
240 # endif
241 _GL_FUNCDECL_RPL (mktime, time_t, (struct tm *__tp) _GL_ARG_NONNULL ((1)));
242 _GL_CXXALIAS_RPL (mktime, time_t, (struct tm *__tp));
243 # else
244 _GL_CXXALIAS_SYS (mktime, time_t, (struct tm *__tp));
245 # endif
246 # if __GLIBC__ >= 2
247 _GL_CXXALIASWARN (mktime);
248 # endif
249 # endif
250
251 /* Convert TIMER to RESULT, assuming local time and UTC respectively. See
252 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime_r.html> and
253 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/gmtime_r.html>. */
254 # if @GNULIB_TIME_R@
255 # if @REPLACE_LOCALTIME_R@
256 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
257 # undef localtime_r
258 # define localtime_r rpl_localtime_r
259 # endif
260 _GL_FUNCDECL_RPL (localtime_r, struct tm *, (time_t const *restrict __timer,
261 struct tm *restrict __result)
262 _GL_ARG_NONNULL ((1, 2)));
263 _GL_CXXALIAS_RPL (localtime_r, struct tm *, (time_t const *restrict __timer,
264 struct tm *restrict __result));
265 # else
266 # if ! @HAVE_DECL_LOCALTIME_R@
267 _GL_FUNCDECL_SYS (localtime_r, struct tm *, (time_t const *restrict __timer,
268 struct tm *restrict __result)
269 _GL_ARG_NONNULL ((1, 2)));
270 # endif
271 _GL_CXXALIAS_SYS (localtime_r, struct tm *, (time_t const *restrict __timer,
272 struct tm *restrict __result));
273 # endif
274 # if @HAVE_DECL_LOCALTIME_R@
275 _GL_CXXALIASWARN (localtime_r);
276 # endif
277 # if @REPLACE_LOCALTIME_R@
278 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
279 # undef gmtime_r
280 # define gmtime_r rpl_gmtime_r
281 # endif
282 _GL_FUNCDECL_RPL (gmtime_r, struct tm *, (time_t const *restrict __timer,
283 struct tm *restrict __result)
284 _GL_ARG_NONNULL ((1, 2)));
285 _GL_CXXALIAS_RPL (gmtime_r, struct tm *, (time_t const *restrict __timer,
286 struct tm *restrict __result));
287 # else
288 # if ! @HAVE_DECL_LOCALTIME_R@
289 _GL_FUNCDECL_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer,
290 struct tm *restrict __result)
291 _GL_ARG_NONNULL ((1, 2)));
292 # endif
293 _GL_CXXALIAS_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer,
294 struct tm *restrict __result));
295 # endif
296 # if @HAVE_DECL_LOCALTIME_R@
297 _GL_CXXALIASWARN (gmtime_r);
298 # endif
299 # endif
300
301 /* Convert TIMER to RESULT, assuming local time and UTC respectively. See
302 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime.html> and
303 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/gmtime.html>. */
304 # if @GNULIB_LOCALTIME@ || @REPLACE_LOCALTIME@
305 # if @REPLACE_LOCALTIME@
306 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
307 # undef localtime
308 # define localtime rpl_localtime
309 # endif
310 _GL_FUNCDECL_RPL (localtime, struct tm *, (time_t const *__timer)
311 _GL_ARG_NONNULL ((1)));
312 _GL_CXXALIAS_RPL (localtime, struct tm *, (time_t const *__timer));
313 # else
314 _GL_CXXALIAS_SYS (localtime, struct tm *, (time_t const *__timer));
315 # endif
316 # if __GLIBC__ >= 2
317 _GL_CXXALIASWARN (localtime);
318 # endif
319 # endif
320
321 # if 0 || @REPLACE_GMTIME@
322 # if @REPLACE_GMTIME@
323 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
324 # undef gmtime
325 # define gmtime rpl_gmtime
326 # endif
327 _GL_FUNCDECL_RPL (gmtime, struct tm *, (time_t const *__timer)
328 _GL_ARG_NONNULL ((1)));
329 _GL_CXXALIAS_RPL (gmtime, struct tm *, (time_t const *__timer));
330 # else
331 _GL_CXXALIAS_SYS (gmtime, struct tm *, (time_t const *__timer));
332 # endif
333 _GL_CXXALIASWARN (gmtime);
334 # endif
335
336 /* Parse BUF as a timestamp, assuming FORMAT specifies its layout, and store
337 the resulting broken-down time into TM. See
338 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/strptime.html>. */
339 # if @GNULIB_STRPTIME@
340 # if ! @HAVE_STRPTIME@
341 _GL_FUNCDECL_SYS (strptime, char *, (char const *restrict __buf,
342 char const *restrict __format,
343 struct tm *restrict __tm)
344 _GL_ARG_NONNULL ((1, 2, 3)));
345 # endif
346 _GL_CXXALIAS_SYS (strptime, char *, (char const *restrict __buf,
347 char const *restrict __format,
348 struct tm *restrict __tm));
349 _GL_CXXALIASWARN (strptime);
350 # endif
351
352 /* Convert *TP to a date and time string. See
353 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/ctime.html>. */
354 # if @GNULIB_CTIME@
355 # if @REPLACE_CTIME@
356 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
357 # define ctime rpl_ctime
358 # endif
359 # ifndef __cplusplus
360 _GL_ATTRIBUTE_DEPRECATED
361 # endif
362 _GL_FUNCDECL_RPL (ctime, char *, (time_t const *__tp)
363 _GL_ARG_NONNULL ((1)));
364 _GL_CXXALIAS_RPL (ctime, char *, (time_t const *__tp));
365 # else
366 _GL_CXXALIAS_SYS (ctime, char *, (time_t const *__tp));
367 # endif
368 # if __GLIBC__ >= 2
369 _GL_CXXALIASWARN (ctime);
370 # endif
371 # endif
372
373 /* Convert *TP to a date and time string. See
374 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html>. */
375 # if @GNULIB_STRFTIME@
376 # if @REPLACE_STRFTIME@
377 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
378 # define strftime rpl_strftime
379 # endif
380 _GL_FUNCDECL_RPL (strftime, size_t,
381 (char *restrict __buf, size_t __bufsize,
382 const char *restrict __fmt, const struct tm *restrict __tp)
383 _GL_ARG_NONNULL ((1, 3, 4)));
384 _GL_CXXALIAS_RPL (strftime, size_t,
385 (char *restrict __buf, size_t __bufsize,
386 const char *restrict __fmt, const struct tm *restrict __tp));
387 # else
388 _GL_CXXALIAS_SYS (strftime, size_t,
389 (char *restrict __buf, size_t __bufsize,
390 const char *restrict __fmt, const struct tm *restrict __tp));
391 # endif
392 # if __GLIBC__ >= 2
393 _GL_CXXALIASWARN (strftime);
394 # endif
395 # endif
396
397 # if defined _GNU_SOURCE && @GNULIB_TIME_RZ@ && ! @HAVE_TIMEZONE_T@
398 /* Functions that use a first-class time zone data type, instead of
399 relying on an implicit global time zone.
400 Inspired by NetBSD. */
401
402 /* Represents a time zone.
403 (timezone_t) NULL stands for UTC. */
404 typedef struct tm_zone *timezone_t;
405
406 /* tzalloc (name)
407 Returns a time zone object for the given time zone NAME. This object
408 represents the time zone that other functions would use it the TZ
409 environment variable was set to NAME.
410 If NAME is NULL, the result represents the time zone that other functions
411 would use it the TZ environment variable was unset.
412 May return NULL if NAME is invalid (this is platform dependent) or
413 upon memory allocation failure. */
414 _GL_FUNCDECL_SYS (tzalloc, timezone_t, (char const *__name));
415 _GL_CXXALIAS_SYS (tzalloc, timezone_t, (char const *__name));
416
417 /* tzfree (tz)
418 Frees a time zone object.
419 The argument must have been returned by tzalloc(). */
420 _GL_FUNCDECL_SYS (tzfree, void, (timezone_t __tz));
421 _GL_CXXALIAS_SYS (tzfree, void, (timezone_t __tz));
422
423 /* localtime_rz (tz, &t, &result)
424 Converts an absolute time T to a broken-down time RESULT, assuming the
425 time zone TZ.
426 This function is like 'localtime_r', but relies on the argument TZ instead
427 of an implicit global time zone. */
428 _GL_FUNCDECL_SYS (localtime_rz, struct tm *,
429 (timezone_t __tz, time_t const *restrict __timer,
430 struct tm *restrict __result) _GL_ARG_NONNULL ((2, 3)));
431 _GL_CXXALIAS_SYS (localtime_rz, struct tm *,
432 (timezone_t __tz, time_t const *restrict __timer,
433 struct tm *restrict __result));
434
435 /* mktime_z (tz, &tm)
436 Normalizes the broken-down time TM and converts it to an absolute time,
437 assuming the time zone TZ. Returns the absolute time.
438 This function is like 'mktime', but relies on the argument TZ instead
439 of an implicit global time zone. */
440 _GL_FUNCDECL_SYS (mktime_z, time_t,
441 (timezone_t __tz, struct tm *restrict __tm)
442 _GL_ARG_NONNULL ((2)));
443 _GL_CXXALIAS_SYS (mktime_z, time_t,
444 (timezone_t __tz, struct tm *restrict __tm));
445
446 /* Time zone abbreviation strings (returned by 'localtime_rz' or 'mktime_z'
447 in the 'tm_zone' member of 'struct tm') are valid as long as
448 - the 'struct tm' argument is not destroyed or overwritten,
449 and
450 - the 'timezone_t' argument is not freed through tzfree(). */
451
452 # endif
453
454 /* Convert TM to a time_t value, assuming UTC. */
455 # if @GNULIB_TIMEGM@
456 # if @REPLACE_TIMEGM@
457 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
458 # undef timegm
459 # define timegm rpl_timegm
460 # endif
461 _GL_FUNCDECL_RPL (timegm, time_t, (struct tm *__tm) _GL_ARG_NONNULL ((1)));
462 _GL_CXXALIAS_RPL (timegm, time_t, (struct tm *__tm));
463 # else
464 # if ! @HAVE_TIMEGM@
465 _GL_FUNCDECL_SYS (timegm, time_t, (struct tm *__tm) _GL_ARG_NONNULL ((1)));
466 # endif
467 _GL_CXXALIAS_SYS (timegm, time_t, (struct tm *__tm));
468 # endif
469 # if __GLIBC__ >= 2
470 _GL_CXXALIASWARN (timegm);
471 # endif
472 # endif
473
474 /* Encourage applications to avoid unsafe functions that can overrun
475 buffers when given outlandish struct tm values. Portable
476 applications should use strftime (or even sprintf) instead. */
477 # if defined GNULIB_POSIXCHECK
478 # undef asctime
479 _GL_WARN_ON_USE (asctime, "asctime can overrun buffers in some cases - "
480 "better use strftime (or even sprintf) instead");
481 # endif
482 # if defined GNULIB_POSIXCHECK
483 # undef asctime_r
484 # if HAVE_RAW_DECL_ASCTIME_R
485 _GL_WARN_ON_USE (asctime_r, "asctime_r can overrun buffers in some cases - "
486 "better use strftime (or even sprintf) instead");
487 # endif
488 # endif
489 # if defined GNULIB_POSIXCHECK
490 # undef ctime
491 _GL_WARN_ON_USE (ctime, "ctime can overrun buffers in some cases - "
492 "better use strftime (or even sprintf) instead");
493 # endif
494 # if defined GNULIB_POSIXCHECK
495 # undef ctime_r
496 # if HAVE_RAW_DECL_CTIME_R
497 _GL_WARN_ON_USE (ctime_r, "ctime_r can overrun buffers in some cases - "
498 "better use strftime (or even sprintf) instead");
499 # endif
500 # endif
501
502 #endif