| '\" t |
| .\" Copyright 1993 David Metcalfe (david@prism.demon.co.uk) |
| .\" |
| .\" SPDX-License-Identifier: Linux-man-pages-copyleft |
| .\" |
| .\" References consulted: |
| .\" Linux libc source code |
| .\" Lewine's _POSIX Programmer's Guide_ (O'Reilly & Associates, 1991) |
| .\" 386BSD man pages |
| .\" Modified Sat Jul 24 19:49:27 1993 by Rik Faith (faith@cs.unc.edu) |
| .\" Modified Fri Apr 26 12:38:55 MET DST 1996 by Martin Schulze (joey@linux.de) |
| .\" Modified 2001-11-13, aeb |
| .\" Modified 2001-12-13, joey, aeb |
| .\" Modified 2004-11-16, mtk |
| .\" |
| .TH ctime 3 (date) "Linux man-pages (unreleased)" |
| .SH NAME |
| asctime, ctime, gmtime, localtime, mktime, asctime_r, ctime_r, gmtime_r, |
| localtime_r \- transform date and time to broken-down time or ASCII |
| .SH LIBRARY |
| Standard C library |
| .RI ( libc ,\~ \-lc ) |
| .SH SYNOPSIS |
| .nf |
| .B #include <time.h> |
| .P |
| .BI "char *asctime(const struct tm *" tm ); |
| .BI "char *asctime_r(const struct tm *restrict " tm , |
| .BI " char " buf "[restrict 26]);" |
| .P |
| .BI "char *ctime(const time_t *" timep ); |
| .BI "char *ctime_r(const time_t *restrict " timep , |
| .BI " char " buf "[restrict 26]);" |
| .P |
| .BI "struct tm *gmtime(const time_t *" timep ); |
| .BI "struct tm *gmtime_r(const time_t *restrict " timep , |
| .BI " struct tm *restrict " result ); |
| .P |
| .BI "struct tm *localtime(const time_t *" timep ); |
| .BI "struct tm *localtime_r(const time_t *restrict " timep , |
| .BI " struct tm *restrict " result ); |
| .P |
| .BI "time_t mktime(struct tm *" tm ); |
| .fi |
| .P |
| .RS -4 |
| Feature Test Macro Requirements for glibc (see |
| .BR feature_test_macros (7)): |
| .RE |
| .P |
| .BR asctime_r (), |
| .BR ctime_r (), |
| .BR gmtime_r (), |
| .BR localtime_r (): |
| .nf |
| _POSIX_C_SOURCE |
| || /* glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE |
| .fi |
| .SH DESCRIPTION |
| The |
| .BR ctime (), |
| .BR gmtime (), |
| and |
| .BR localtime () |
| functions all take |
| an argument of data type \fItime_t\fP, which represents calendar time. |
| When interpreted as an absolute time value, it represents the number of |
| seconds elapsed since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). |
| .P |
| The |
| .BR asctime () |
| and |
| .BR mktime () |
| functions both take an argument |
| representing broken-down time, which is a representation |
| separated into year, month, day, and so on. |
| .P |
| Broken-down time is stored in the structure |
| .IR tm , |
| described in |
| .BR tm (3type). |
| .P |
| The call |
| .BI ctime( t ) |
| is equivalent to |
| .BI asctime(localtime( t )) \fR. |
| It converts the calendar time \fIt\fP into a |
| null-terminated string of the form |
| .P |
| .in +4n |
| .EX |
| "Wed Jun 30 21:49:08 1993\[rs]n" |
| .EE |
| .in |
| .P |
| The abbreviations for the days of the week are "Sun", "Mon", "Tue", "Wed", |
| "Thu", "Fri", and "Sat". |
| The abbreviations for the months are "Jan", |
| "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", and |
| "Dec". |
| The return value points to a statically allocated string which |
| might be overwritten by subsequent calls to any of the date and time |
| functions. |
| The function also sets the external variables \fItzname\fP, |
| \fItimezone\fP, and \fIdaylight\fP as if it called |
| .BR tzset (3). |
| The reentrant version |
| .BR ctime_r () |
| does the same, but stores the |
| string in a user-supplied buffer |
| which should have room for at least 26 bytes. |
| It need not |
| set \fItzname\fP, \fItimezone\fP, and \fIdaylight\fP. |
| .P |
| The |
| .BR gmtime () |
| function converts the calendar time \fItimep\fP to |
| broken-down time representation, expressed in Coordinated Universal Time |
| (UTC). |
| It may return NULL when the year does not fit into an integer. |
| The return value points to a statically allocated struct which might be |
| overwritten by subsequent calls to any of the date and time functions. |
| The |
| .BR gmtime_r () |
| function does the same, but stores the data in a |
| user-supplied struct. |
| .P |
| The |
| .BR localtime () |
| function converts the calendar time \fItimep\fP to |
| broken-down time representation, |
| expressed relative to the user's specified timezone. |
| The function also sets the external variables \fItzname\fP, |
| \fItimezone\fP, and \fIdaylight\fP as if it called |
| .BR tzset (3). |
| The return value points to a statically allocated struct which might be |
| overwritten by subsequent calls to any of the date and time functions. |
| The |
| .BR localtime_r () |
| function does the same, but stores the data in a |
| user-supplied struct. |
| It need not set \fItzname\fP, \fItimezone\fP, and \fIdaylight\fP. |
| .P |
| The |
| .BR asctime () |
| function converts the broken-down time value |
| \fItm\fP into a null-terminated string with the same format as |
| .BR ctime (). |
| The return value points to a statically allocated string which might be |
| overwritten by subsequent calls to any of the date and time functions. |
| The |
| .BR asctime_r () |
| function does the same, but stores the string in |
| a user-supplied buffer which should have room for at least 26 bytes. |
| .P |
| The |
| .BR mktime () |
| function converts a broken-down time structure, expressed |
| as local time, to calendar time representation. |
| The function ignores |
| the values supplied by the caller in the |
| .I tm_wday |
| and |
| .I tm_yday |
| fields. |
| The value specified in the |
| .I tm_isdst |
| field informs |
| .BR mktime () |
| whether or not daylight saving time (DST) |
| is in effect for the time supplied in the |
| .I tm |
| structure: |
| a positive value means DST is in effect; |
| zero means that DST is not in effect; |
| and a negative value means that |
| .BR mktime () |
| should (use timezone information and system databases to) |
| attempt to determine whether DST is in effect at the specified time. |
| .P |
| The |
| .BR mktime () |
| function modifies the fields of the |
| .I tm |
| structure as follows: |
| .I tm_wday |
| and |
| .I tm_yday |
| are set to values determined from the contents of the other fields; |
| if structure members are outside their valid interval, they will be |
| normalized (so that, for example, 40 October is changed into 9 November); |
| .I tm_isdst |
| is set (regardless of its initial value) |
| to a positive value or to 0, respectively, |
| to indicate whether DST is or is not in effect at the specified time. |
| The function also sets the external variables \fItzname\fP, |
| \fItimezone\fP, and \fIdaylight\fP as if it called |
| .BR tzset (3). |
| .P |
| If the specified broken-down |
| time cannot be represented as calendar time (seconds since the Epoch), |
| .BR mktime () |
| returns |
| .I (time_t)\ \-1 |
| and does not alter the |
| members of the broken-down time structure. |
| .SH RETURN VALUE |
| On success, |
| .BR gmtime () |
| and |
| .BR localtime () |
| return a pointer to a |
| .IR "struct\ tm" . |
| .P |
| On success, |
| .BR gmtime_r () |
| and |
| .BR localtime_r () |
| return the address of the structure pointed to by |
| .IR result . |
| .P |
| On success, |
| .BR asctime () |
| and |
| .BR ctime () |
| return a pointer to a string. |
| .P |
| On success, |
| .BR asctime_r () |
| and |
| .BR ctime_r () |
| return a pointer to the string pointed to by |
| .IR buf . |
| .P |
| On success, |
| .BR mktime () |
| returns the calendar time (seconds since the Epoch), |
| expressed as a value of type |
| .IR time_t . |
| .P |
| On error, |
| .BR mktime () |
| returns the value |
| .IR "(time_t)\ \-1" , |
| and leaves the |
| .I tm->tm_wday |
| member unmodified. |
| The remaining functions return NULL on error. |
| On error, |
| .I errno |
| is set to indicate the error. |
| .SH ERRORS |
| .TP |
| .B EOVERFLOW |
| The result cannot be represented. |
| .SH ATTRIBUTES |
| For an explanation of the terms used in this section, see |
| .BR attributes (7). |
| .TS |
| allbox; |
| lb lb lbx |
| l l l. |
| Interface Attribute Value |
| T{ |
| .na |
| .nh |
| .BR asctime () |
| T} Thread safety T{ |
| .na |
| .nh |
| MT-Unsafe race:asctime locale |
| T} |
| T{ |
| .na |
| .nh |
| .BR asctime_r () |
| T} Thread safety T{ |
| .na |
| .nh |
| MT-Safe locale |
| T} |
| T{ |
| .na |
| .nh |
| .BR ctime () |
| T} Thread safety T{ |
| .na |
| .nh |
| MT-Unsafe race:tmbuf |
| race:asctime env locale |
| T} |
| T{ |
| .na |
| .nh |
| .BR ctime_r (), |
| .BR gmtime_r (), |
| .BR localtime_r (), |
| .BR mktime () |
| T} Thread safety T{ |
| .na |
| .nh |
| MT-Safe env locale |
| T} |
| T{ |
| .na |
| .nh |
| .BR gmtime (), |
| .BR localtime () |
| T} Thread safety T{ |
| .na |
| .nh |
| MT-Unsafe race:tmbuf env locale |
| T} |
| .TE |
| .SH VERSIONS |
| POSIX doesn't specify the parameters of |
| .BR ctime_r () |
| to be |
| .IR restrict ; |
| that is specific to glibc. |
| .P |
| In many implementations, including glibc, a 0 in |
| .I tm_mday |
| is interpreted as meaning the last day of the preceding month. |
| .P |
| According to POSIX.1, |
| .BR localtime () |
| is required to behave as though |
| .BR tzset (3) |
| was called, while |
| .BR localtime_r () |
| does not have this requirement. |
| .\" See http://thread.gmane.org/gmane.comp.time.tz/2034/ |
| For portable code, |
| .BR tzset (3) |
| should be called before |
| .BR localtime_r (). |
| .SH STANDARDS |
| .TP |
| .BR asctime () |
| .TQ |
| .BR ctime () |
| .TQ |
| .BR gmtime () |
| .TQ |
| .BR localtime () |
| .TQ |
| .BR mktime () |
| C23, POSIX.1-2024. |
| .TP |
| .BR gmtime_r () |
| .TQ |
| .BR localtime_r () |
| POSIX.1-2024. |
| .TP |
| .BR asctime_r () |
| .TQ |
| .BR ctime_r () |
| None. |
| .SH HISTORY |
| .TP |
| .BR gmtime () |
| .TQ |
| .BR localtime () |
| .TQ |
| .BR mktime () |
| C89, POSIX.1-1988. |
| .TP |
| .BR asctime () |
| .TQ |
| .BR ctime () |
| C89, POSIX.1-1988. |
| Marked obsolescent in C23 and in POSIX.1-2008 (recommending |
| .BR strftime (3)). |
| .TP |
| .BR gmtime_r () |
| .TQ |
| .BR localtime_r () |
| POSIX.1-1996. |
| .TP |
| .BR asctime_r () |
| .TQ |
| .BR ctime_r () |
| POSIX.1-1996. |
| Marked obsolescent in POSIX.1-2008. |
| Removed in POSIX.1-2024 (recommending |
| .BR strftime (3)). |
| .SH CAVEATS |
| .SS Thread safety |
| The four functions |
| .BR asctime (), |
| .BR ctime (), |
| .BR gmtime (), |
| and |
| .BR localtime () |
| return a pointer to static data and hence are not thread-safe. |
| The thread-safe versions, |
| .BR asctime_r (), |
| .BR ctime_r (), |
| .BR gmtime_r (), |
| and |
| .BR localtime_r (), |
| are specified by SUSv2. |
| .P |
| POSIX.1 says: |
| "The |
| .BR asctime (), |
| .BR ctime (), |
| .BR gmtime (), |
| and |
| .BR localtime () |
| functions shall return values in one of two static objects: |
| a broken-down time structure and an array of type |
| .IR char . |
| Execution of any of the functions that return a pointer to one of these |
| object types may overwrite the information in any object of the same type |
| pointed to by the value returned from any previous call to any of them." |
| This can occur in the glibc implementation. |
| .SS mktime() |
| .I (time_t) \-1 |
| can represent a valid time |
| (one second before the Epoch). |
| To determine whether |
| .BR mktime () |
| failed, |
| one must use the |
| .I tm->tm_wday |
| field. |
| See the example program in EXAMPLES. |
| .P |
| The handling of a non-negative |
| .I tm_isdst |
| in |
| .BR mktime () |
| is poorly specified, |
| and passing a value that is incorrect for the time specified |
| yields unspecified results. |
| Since |
| .BR mktime () |
| is one of the few functions that knows when DST is in effect, |
| providing a correct value may be difficult. |
| One workaround for this is to call |
| .BR mktime () |
| twice, |
| once with |
| .I tm_isdst |
| set to zero, |
| and once with |
| .I tm_isdst |
| set to a positive value, |
| and discarding the results from the call that changes it. |
| If neither call changes |
| .I tm_isdst |
| then the time specified probably happens during a fall-back period |
| where DST begins or ends, |
| and both results are valid |
| but represent two different times. |
| If both calls change it, that could indicate a fall-forward transition, |
| or some other reason why the time specified does not exist. |
| .P |
| The specification of time zones and daylight saving time |
| are up to regional governments, change often, |
| and may include discontinuities beyond |
| .IR mktime 's |
| ability to document a result. |
| For example, a change in the timezone definition |
| may cause a clock time to be repeated or skipped |
| without a corresponding DST change. |
| .SH EXAMPLES |
| The program below defines a wrapper that |
| allows detecting invalid and ambiguous times, |
| with |
| .B EINVAL |
| and |
| .BR ENOTUNIQ , |
| respectively. |
| .P |
| The following shell session shows sample runs of the program: |
| .P |
| .in +4n |
| .EX |
| .RB $\~ "TZ=UTC ./a.out 1969 12 31 23 59 59 0" ; |
| \-1 |
| $ |
| .RB $\~ "export TZ=Europe/Madrid" ; |
| $ |
| .RB $\~ "./a.out 2147483647 2147483647 00 00 00 00 -1" ; |
| a.out: mktime: Value too large for defined data type |
| $ |
| .RB $\~ "./a.out 2024 08 23 00 17 53 \-1" ; |
| 1724365073 |
| .RB $\~ "./a.out 2024 08 23 00 17 53 0" ; |
| a.out: my_mktime: Invalid argument |
| 1724368673 |
| .RB $\~ "./a.out 2024 08 23 00 17 53 1" ; |
| 1724365073 |
| $ |
| .RB $\~ "./a.out 2024 02 23 00 17 53 \-1" ; |
| 1708643873 |
| .RB $\~ "./a.out 2024 02 23 00 17 53 0" ; |
| 1708643873 |
| .RB $\~ "./a.out 2024 02 23 00 17 53 1" ; |
| a.out: my_mktime: Invalid argument |
| 1708640273 |
| $ |
| .RB $\~ "./a.out 2023 03 26 02 17 53 \-1" ; |
| a.out: my_mktime: Invalid argument |
| 1679793473 |
| $ |
| .RB $\~ "./a.out 2023 10 29 02 17 53 \-1" ; |
| a.out: my_mktime: Name not unique on network |
| 1698542273 |
| .RB $\~ "./a.out 2023 10 29 02 17 53 0" ; |
| 1698542273 |
| .RB $\~ "./a.out 2023 10 29 02 17 53 1" ; |
| 1698538673 |
| $ |
| .RB $\~ "./a.out 2023 02 29 12 00 00 \-1" ; |
| a.out: my_mktime: Invalid argument |
| 1677668400 |
| .EE |
| .SS Program source: mktime.c |
| \& |
| .\" SRC BEGIN (mktime.c) |
| .EX |
| #include <err.h> |
| #include <errno.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <time.h> |
| \& |
| #define is_signed(T) ((T) \-1 < 1) |
| \& |
| time_t my_mktime(struct tm *tp); |
| \& |
| int |
| main(int argc, char *argv[]) |
| { |
| char **p; |
| time_t t; |
| struct tm tm; |
| \& |
| if (argc != 8) { |
| fprintf(stderr, "Usage: %s yyyy mm dd HH MM SS isdst\[rs]n", argv[0]); |
| exit(EXIT_FAILURE); |
| } |
| \& |
| p = &argv[1]; |
| tm.tm_year = atoi(*p++) \- 1900; |
| tm.tm_mon = atoi(*p++) \- 1; |
| tm.tm_mday = atoi(*p++); |
| tm.tm_hour = atoi(*p++); |
| tm.tm_min = atoi(*p++); |
| tm.tm_sec = atoi(*p++); |
| tm.tm_isdst = atoi(*p++); |
| \& |
| errno = 0; |
| tm.tm_wday = \-1; |
| t = my_mktime(&tm); |
| if (tm.tm_wday == \-1) |
| err(EXIT_FAILURE, "mktime"); |
| if (errno == EINVAL || errno == ENOTUNIQ) |
| warn("my_mktime"); |
| \& |
| if (is_signed(time_t)) |
| printf("%jd\[rs]n", (intmax_t) t); |
| else |
| printf("%ju\[rs]n", (uintmax_t) t); |
| \& |
| exit(EXIT_SUCCESS); |
| } |
| \& |
| time_t |
| my_mktime(struct tm *tp) |
| { |
| int e, isdst; |
| time_t t; |
| struct tm tm; |
| unsigned char wday[sizeof(tp\->tm_wday)]; |
| \& |
| e = errno; |
| \& |
| tm = *tp; |
| isdst = tp\->tm_isdst; |
| \& |
| memcpy(wday, &tp\->tm_wday, sizeof(wday)); |
| tp\->tm_wday = \-1; |
| t = mktime(tp); |
| if (tp\->tm_wday == \-1) { |
| memcpy(&tp\->tm_wday, wday, sizeof(wday)); |
| return \-1; |
| } |
| \& |
| if (isdst == \-1) |
| tm.tm_isdst = tp\->tm_isdst; |
| \& |
| if ( tm.tm_sec != tp\->tm_sec |
| || tm.tm_min != tp\->tm_min |
| || tm.tm_hour != tp\->tm_hour |
| || tm.tm_mday != tp\->tm_mday |
| || tm.tm_mon != tp\->tm_mon |
| || tm.tm_year != tp\->tm_year |
| || tm.tm_isdst != tp\->tm_isdst) |
| { |
| errno = EINVAL; |
| return t; |
| } |
| \& |
| if (isdst != \-1) |
| goto out; |
| \& |
| tm = *tp; |
| tm.tm_isdst = !tm.tm_isdst; |
| \& |
| tm.tm_wday = \-1; |
| mktime(&tm); |
| if (tm.tm_wday == \-1) |
| goto out; |
| \& |
| if (tm.tm_isdst != tp\->tm_isdst) { |
| errno = ENOTUNIQ; |
| return t; |
| } |
| out: |
| errno = e; |
| return t; |
| } |
| .EE |
| .\" SRC END |
| .SH SEE ALSO |
| .BR date (1), |
| .BR gettimeofday (2), |
| .BR time (2), |
| .BR utime (2), |
| .BR clock (3), |
| .BR difftime (3), |
| .BR strftime (3), |
| .BR strptime (3), |
| .BR timegm (3), |
| .BR tzset (3), |
| .BR time (7) |