TM(3ast) TM(3ast)

# [NAME](#NAME)

tm - seconds resolution time conversion support

# [SYNOPSIS](#SYNOPSIS)

#include &lt;tm.h&gt;

# [DESCRIPTION](#DESCRIPTION)

The *tm* library supports conversion between string date specifications, seconds resolution time\_t clock values and Tm\_t. Tm\_t contains the elements of struct tm along with these additions:

unsigned \_ast\_int4\_t tm\_nsec

The subsecond portion of the time in nanoseconds.

Tm\_zone\_t* tm\_zone

The time zone name.

localtime() and gmtime() (see [**ctime**(3)](/man/os/ksh/ctime.3)) are used to determine local time zone and savings time information.

time\_t values are the number of seconds since the epoch, **Jan 1 00:00:00 UTC 1970**, with leap seconds omitted.

The global variable int tm\_info.flags contains flags that allow all programs using the library to be controlled in a consistent manner. tm\_info.flags is initialized by the tminit() routine described below, and may be explicitly reset after tminit() is called. The flags are:

TM\_ADJUST

Set by tminit() if localtime() and gmtime() do not compensate for leap seconds.

TM\_LEAP

time\_t values are interpreted as if they include leap seconds. Set by tminit() if the leap option is set in the TM\_OPTIONS environment variable.

TM\_UTC

Times are relative to **UTC** (universal coordinated time, i.e., **GMT**). Otherwise times are relative to the local time zone. Set by tminit() if the time zone name matches one of tm\_info.format\[43] through tm\_info.format\[46] described below. If the time zone name is not determined by localtime() then the environment variables TZNAME (as described in BSD 4.3) and TZ (as described in System V) are checked, in order. If this fails then the time zone name is constructed using the local time zone offset.

The routines are:

time\_t tmdate(const char* date, char\** end, time\_t* clock)

Parses the date specification date using the tm\_info.format string table (described below) and returns the equivalent time\_t value. If non-NULL, end is set to the position of the first unrecognized character in date. clock is used to provide default values for omitted components in date. If clock is NULL then the current time is used.

Tm\_t* tmfix(Tm\_t* tp)

Corrects any out of bounds fields in tp and returns tp as its value. The corrections start with tp-&gt;tm\_sec and propagate down to tp-&gt;tm\_year. For example, if tp-&gt;tm\_sec were 61 then it would change to 1 and tp-&gt;tm\_min would be incremented by 1, and so on. tp-&gt;tm\_isdst is not changed -- call tmtime() to determine its proper value after the tmfix() adjustments.

char* tmfmt(char* buf, size\_t len, const char* format, time\_t* clock)

Formats the date pointed to by clock into the buffer buf with size len bytes according to the format specification format. If format is NULL or empty then the string tm\_info.format\[40] is used. If clock is NULL then the current time is used. A pointer to the end of buf (i.e., the terminating '\\0') is returned.

format is in [**printf**(3)](/man/os/ksh/printf.3) style, where %*field* names a fixed size field, zero padded if necessary, and *\\c* and *\\nnn* sequences are as in C. Invalid %*field* specifications and all other characters are copied without change. *field* may be preceded by **%-** to turn off padding or **%\_** to pad with space, otherwise numeric fields are padded with **0** and string fields are padded with space. *field* may also be preceded by **E** for alternate era representation or **O** for alternate digit representation (if supported by the current locale). Finally, an integral *width* preceding *field* truncates the field to *width* characters. sequences are interpreted as in the C language. String field values are taken from the tm\_info.format string table. The *fields* are:

**%**

**%** character.

[**a**](#a)

Abbreviated weekday name.

[**A**](#A)

Full weekday name.

[**b**](#b)

Abbreviated month name.

[**B**](#B)

Full month name.

[**c**](#c)

[**ctime**(3)](/man/os/ksh/ctime.3) style date without the trailing **newline**.

[**C**](#C)

[**date**(1)](/man/os/ksh/date.1) style date.

[**d**](#d)

Day of month number.

[**D**](#D)

Date as *mm*/*dd*/*yy*.

[**e**](#e)

Blank padded day of month number.

[**E**](#E)

Unpadded day of month number.

[**f**](#f)

Date as *%Y.%m.%d-%H:%M:%S*.

[**F**](#F)

ISO 8601:2000 standard date format; equivalent to *%Y-%m-%d*.

[**h**](#h)

Abbreviated month name.

[**H**](#H)

24-hour clock hour, zero-padded.

[**i**](#i)

International [**date**(1)](/man/os/ksh/date.1) date that includes the time zone type name (tm\_info.format\[107]).

[**I**](#I)

12-hour clock hour, zero-padded.

[**j**](#j)

1-offset Julian date.

[**J**](#J)

0-offset Julian date.

[**k**](#k)

24-hour clock hour, blank-padded.

[**K**](#K)

Language neutral, all numeric, no embedded space date with larger to smaller time units from left to right, suitable for sorting: '"%Y-%m-%d+%H:%M:%S"'.

[**l**](#l)

12-hour clock hour, blank-padded.

[**m**](#m)

Month number.

[**M**](#M)

Minutes.

[**n**](#n)

**newline** character.

[**N**](#N)

Nanoseconds 000000000-999999999.

[**p**](#p)

Meridian (e.g., **AM** or **PM**).

[**P**](#P)

Lowercase meridian (e.g., **am** or **pm**).

[**q**](#q)

The quarter of the year.

**%Q&lt;delim&gt;recent&lt;delim&gt;distant&lt;delim&gt;**

Recent dates are formatted with *recent* and distant dates are formatted with *distant*, where *&lt;delim&gt;* is any character not appearing in *recent* or *distant*.

[**r**](#r)

12-hour time as *hh*:*mm*:*ss* *meridian*.

[**R**](#R)

24-hour time as *hh*:*mm*.

[**s**](#s)

Seconds since the epoch. .*prec* preceding **s** appends *prec* nanosecond digits, **9** if *prec* is omitted.

[**S**](#S)

*seconds.subseconds* since the epoch.

[**t**](#t)

**tab** character.

[**T**](#T)

24-hour time as *hh*:*mm*:*ss*.

[**u**](#u)

Weekday number with 1 for Monday, 7 for Sunday.

[**U**](#U)

Week number with Sunday as the first day.

[**V**](#V)

ISO week number (i18n is *fun*).

[**w**](#w)

Weekday number with 0 for Sunday, 6 for Saturday.

[**W**](#W)

Week number with Monday as the first day.

[**x**](#x)

Local date style, using tm\_info.format\[39], that includes the month, day and year.

[**X**](#X)

Local time style, using tm\_info.format\[38], that includes the hours and minutes.

[**y**](#y)

2-digit year (you'll be sorry).

[**Y**](#Y)

4-digit year.

[**z**](#z)

Time zone *SHHMM* west of UTC offset where *S* is **+** or **-**.

[**Z**](#Z)

Time zone name.

=\[=]]\[-+]]*flag*

Set (default or +) or clear (-) *flag* in tm\_info.flags for the remainder of *format*, or for the remainder of the process if **==** is specified. *flag* may be:

[**l**](#l~2)

(TM\_LEAP) Enable leap second adjustments.

[**s**](#s~2)

(TM\_SUBSECOND) Append nanosecond **.%N** to **%S**.

[**u**](#u~2)

(TM\_UTC) UTC time zone.

**#**

Equivalent to **%s**.

*?alternate*

The *alternate* format is a default format override has not been specified. e.g., [**ls**(1)](/man/os/ksh/ls.1) uses **%?%l**. Export **TM\_OPTIONS="format='override'"** to override the default.

void tminit(Tm\_zone\_t* zone, time\_t now, const char newzone)

Implicitly called by the other *tm* library routines to initialize global data, including the tm\_info.format table and the tm\_info.flags global flags. Global data should only be modified after an explicit call to tminit. If zone != 0 then it specifies a time zone other that the local time zone.

void tmset(Tm\_zone\_t* zone, time\_t now, const char newzone);

tmset sets the reference timezone to zone. tm\_info.local points to the local timezone and tm\_info.zone points to the reference timezone at a given time now if newzone is non-zero, or to the current reference timezone otherwise.

time\_t tmleap(time\_t* clock)

Returns a time\_t value for the time pointed to by clock with leap seconds adjusted for external routines that do not handle leap seconds. If clock is NULL then the current time is used. Adjustments are only done if the TM\_ADJUST flag is set in tm\_info.flags.

Tm\_t* tmmake(time\_t* clock)

Returns a pointer to the Tm\_t struct corresponding to the time pointed to by clock. If clock is NULL then the current time is used.

time\_t tmtime(Tm\_t* tp, int west)

Returns the time\_t value corresponding to tp. If west is TM\_LOCALZONE then tm is relative to the local time zone, otherwise west is the number of minutes west of **UTC** with daylight savings time taken into account. tp-&gt;tm\_wday, tp-&gt;tm\_yday and tp-&gt;tm\_isdst are ignored in the conversion.

The library routines use a table of date strings pointed to by char\** tm\_info.format. The indices in tm\_info.format are fixed by category. tm\_info.format may be changed to point to other tables according to local language and date conventions. The contents by index (showing the USA English values) are:

**0-11**

3-character abbreviated month names.

**12-23**

Full month names.

**24-30**

3-character abbreviated weekday names.

**31-37**

Full weekday names.

**38**

tmfmt() local time format used by the **%X** field.

**39**

tmfmt() local date format used by the **%x** field.

**40**

tmfmt() format used if the format argument is NULL or empty.

**41-42**

Meridian names: AM, PM.

**43-46**

**UTC** time zone names: UTC, UCT, CUT, GMT.

**47-50**

Daylight savings time suffix names: DST.

**51-54**

Suffixes to be ignored when matching strings in tmfmt().

**55-61**

Time part names: second, hour, minute, day, week, month, year.

**62-65**

Hours of the day names: midnight, morning, noon, evening.

**66-68**

Relative day names: yesterday, today, tomorrow.

**69-71**

Past relative time references: last, ago, past.

**72-75**

Current relative time references: this, now, current.

**75-77**

Future relative time references: next, hence, coming.

**78-80**

Exact relative time references: exactly.

**81-84**

Noise words to be ignored: at, in, on.

**85-94**

Ordinal suffixes: st, nd, rd, th, th, th, th, th, th, th.

**95-104**

Digit names.

**105**

The tmfmt() format equivalent for [**ctime**(3)](/man/os/ksh/ctime.3): '"%a%b%e%T%Y"'.

**106**

The tmfmt() [**date**(1)](/man/os/ksh/date.1) default format: '"%a%b%e%T%Z%Y"'.

**107**

The tmfmt() [**date**(1)](/man/os/ksh/date.1) international format: '"%a%b%e%T%z%Z%Y"'

**108**

The tmfmt() [**ls**(1)](/man/os/ksh/ls.1) recent date format: '"%b%e%H:%M"'.

**109**

The tmfmt() [**ls**(1)](/man/os/ksh/ls.1) distant date format: '"%b%e%Y"'.

**110**

The tmfmt() [**date**(1)](/man/os/ksh/date.1) meridian date format: '"%I:%M:%S%p"'.

**111**

The ERA name.

**112**

ERA alternative for **39**.

**113**

ERA alternative for **38**.

**114**

ERA alternative for **40**.

**115**

The ERA year.

**116-125**

Ordinal names: first, *no second!*, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth.

**126-128**

Final time references, as in *the last in the list*: final, ending, nth.

Low level support functions and data are described in &lt;tm.h&gt;.

# [EXAMPLES](#EXAMPLES)

```
#include <tm.h>
int main(void) {


    int       i;


    time_t    t;


    char      buf[128];


    struct {


        char* date;


        char* format;


    }         x[] = {


        "now",                 "%i",


        "2 months ago",        "%C",


        "this Wednesday noon", "%x %I:%M %p",


        "last December 25",    "%A",


        0,                     0


    };


    for (i = 0; x[i].date; i++) {


        t = tmdate(x[i].date, NULL, NULL);


        (void)tmfmt(buf, sizeof(buf), x[i].format, &t);


        puts(buf);


    }
}
```

produces

```
Fri Sep 30 12:10:14 USA EDT 1988
Fri Jul  1 00:00:00 EDT 1988
10/05/88 12:00 PM
Friday
```

# [SEE ALSO](#SEE_ALSO)

[**date**(1)](/man/os/ksh/date.1), [**time**(2)](/man/os/ksh/time.2), [**ctime**(3)](/man/os/ksh/ctime.3)

# [BUGS](#BUGS)

The C library static struct tm values may get clobbered by *tm* library routines as the [**ctime**(3)](/man/os/ksh/ctime.3) and [**localtime**(3)](/man/os/ksh/localtime.3) routines typically return pointers to a single static struct tm area. tmdate() uses an internal international time zone name table that will probably always be incomplete.

---

Document: tm(3ast) from ksh 1.0.10-r36 (Chainguard OS)
Source: https://github.com/ksh93/ksh
