#### 22.5.3 Broken-down Time ¶

Simple calendar times represent absolute times as elapsed times since an epoch. This is convenient for computation, but has no relation to the way people normally think of calendar time. By contrast, broken-down time is a binary representation of calendar time separated into year, month, day, and so on. Although broken-down time values are painful to calculate with, they are useful for printing human readable time information.

A broken-down time value is always relative to a choice of time zone, and it also indicates which time zone that is.

The symbols in this section are declared in the header file `time.h`.

Data Type: struct tm ¶

  This is the data type used to represent a broken-down time. The structure contains at least the following members, which can appear in any order.

  `int tm_sec`

    This is the number of full seconds since the top of the minute (normally in the range `0` through `59`, but the actual upper limit is `60`, to allow for leap seconds if leap second support is available).

  `int tm_min`

    This is the number of full minutes since the top of the hour (in the range `0` through `59`).

  `int tm_hour`

    This is the number of full hours past midnight (in the range `0` through `23`).

  `int tm_mday`

    This is the ordinal day of the month (in the range `1` through `31`). Watch out for this one! As the only ordinal number in the structure, it is inconsistent with the rest of the structure.

  `int tm_mon`

    This is the number of full calendar months since the beginning of the year (in the range `0` through `11`). Watch out for this one! People usually use ordinal numbers for month-of-year (where January = 1).

  `int tm_year`

    This is the number of full calendar years since 1900.

  `int tm_wday`

    This is the number of full days since Sunday (in the range `0` through `6`).

  `int tm_yday`

    This is the number of full days since the beginning of the year (in the range `0` through `365`).

  `int tm_isdst` ¶

    This is a flag that indicates whether daylight saving time is (or was, or will be) in effect at the time described. The value is positive if daylight saving time is in effect, zero if it is not, and negative if the information is not available. Although this flag is useful when passing a broken-down time to the `mktime` function, for other uses this flag should be ignored and the `tm_gmtoff` and `tm_zone` fields should be inspected instead.

  `long int tm_gmtoff`

    This field describes the time zone that was used to compute this broken-down time value, including any adjustment for daylight saving; it is the number of seconds that you must add to UTC to get local time. You can also think of this as the number of seconds east of the Prime Meridian. For example, for U.S. Eastern Standard Time, the value is `-5*60*60`.

  `const char *tm_zone`

    This field is the abbreviation for the time zone that was used to compute this broken-down time value.

  Portability note: The `tm_gmtoff` and `tm_zone` fields are derived from BSD and are POSIX extensions to ISO C. Code intended to be portable to operating systems that lack these fields can instead use time zone state variables, although those variables are unreliable when the `TZ` environment variable has a geographical format. See State Variables for Time Zones.

Function: `struct tm *` localtime `(const time_t *time)` ¶

  Preliminary: | MT-Unsafe race:tmbuf env locale | AS-Unsafe heap lock | AC-Unsafe lock mem fd | See POSIX Safety Concepts.

  The `localtime` function converts the simple time pointed to by time to broken-down time representation, expressed relative to the user’s specified time zone.

  The return value is a pointer to a static broken-down time structure, which might be overwritten by subsequent calls to `gmtime` or `localtime`. (No other library function overwrites the contents of this object.) In the GNU C Library, the structure’s `tm_zone` points to a string with a storage lifetime that lasts indefinitely; on other platforms, the lifetime may expire when the `TZ` environment variable is changed.

  The return value is the null pointer if time cannot be represented as a broken-down time; typically this is because the year cannot fit into an `int`.

  Calling `localtime` also sets the time zone state as if `tzset` were called. See State Variables for Time Zones.

Using the `localtime` function is a big problem in multi-threaded programs. The result is returned in a static buffer and this is used in all threads. A variant function avoids this problem.

Function: `struct tm *` localtime_r `(const time_t *time, struct tm *resultp)` ¶

  Preliminary: | MT-Safe env locale | AS-Unsafe heap lock | AC-Unsafe lock mem fd | See POSIX Safety Concepts.

  The `localtime_r` function works just like the `localtime` function. It takes a pointer to a variable containing a simple time and converts it to the broken-down time format.

  But the result is not placed in a static buffer. Instead it is placed in the object of type `struct tm` to which the parameter resultp points. Also, the time zone state is not necessarily set as if `tzset` were called.

  If the conversion is successful the function returns a pointer to the object the result was written into, i.e., it returns resultp.

Function: `struct tm *` gmtime `(const time_t *time)` ¶

  Preliminary: | MT-Unsafe race:tmbuf env locale | AS-Unsafe heap lock | AC-Unsafe lock mem fd | See POSIX Safety Concepts.

  This function is similar to `localtime`, except that the broken-down time is expressed as UTC rather than relative to a local time zone. The broken-down time’s `tm_gmtoff` is 0, and its `tm_zone` is a string `"UTC"` with static storage duration.

As for the `localtime` function we have the problem that the result is placed in a static variable. A thread-safe replacement is also provided for `gmtime`.

Function: `struct tm *` gmtime_r `(const time_t *time, struct tm *resultp)` ¶

  Preliminary: | MT-Safe env locale | AS-Unsafe heap lock | AC-Unsafe lock mem fd | See POSIX Safety Concepts.

  This function is similar to `localtime_r`, except that it converts just like `gmtime` the given time as UTC.

  If the conversion is successful the function returns a pointer to the object the result was written into, i.e., it returns resultp.

Function: `time_t` mktime `(struct tm *brokentime)` ¶

  Preliminary: | MT-Safe env locale | AS-Unsafe heap lock | AC-Unsafe lock mem fd | See POSIX Safety Concepts.

  The `mktime` function converts a broken-down time structure to a simple time representation. It also normalizes the contents of the broken-down time structure, and fills in some components based on the values of the others.

  The `mktime` function ignores the specified contents of the `tm_wday`, `tm_yday`, `tm_gmtoff`, and `tm_zone` members of the broken-down time structure. It uses the values of the other components to determine the calendar time; it’s permissible for these components to have unnormalized values outside their normal ranges. The last thing that `mktime` does is adjust the components of the brokentime structure, including the members that were initially ignored.

  If the specified broken-down time cannot be represented as a simple time, `mktime` returns a value of `(time_t)(-1)` and does not modify the contents of brokentime.

  Calling `mktime` also sets the time zone state as if `tzset` were called; `mktime` uses this information instead of brokentime’s initial `tm_gmtoff` and `tm_zone` members. See State Variables for Time Zones.

Function: `time_t` timelocal `(struct tm *brokentime)` ¶

  Preliminary: | MT-Safe env locale | AS-Unsafe heap lock | AC-Unsafe lock mem fd | See POSIX Safety Concepts.

  `timelocal` is functionally identical to `mktime`, but more mnemonically named. Note that it is the inverse of the `localtime` function.

  Portability note: `mktime` is essentially universally available. `timelocal` is rather rare.

Function: `time_t` timegm `(struct tm *brokentime)` ¶

  Preliminary: | MT-Safe env locale | AS-Unsafe heap lock | AC-Unsafe lock mem fd | See POSIX Safety Concepts.

  `timegm` is functionally identical to `mktime` except it always takes the input values to be UTC regardless of any local time zone setting.

  Note that `timegm` is the inverse of `gmtime`.

  Portability note: `mktime` is essentially universally available. Although `timegm` is standardized by C23, some other systems lack it; to be portable to them, you can set the `TZ` environment variable to UTC, call `mktime`, then set `TZ` back.