1.fp 5 CW
2.de Af
3.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
4.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
5..
6.de aF
7.ie \\$3 .ft \\$1
8.el \{\
9.ds ;G \&
10.nr ;G \\n(.f
11.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
12\\*(;G
13.ft \\n(;G \}
14..
15.de L
16.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
17..
18.de LR
19.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
20..
21.de RL
22.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
23..
24.de EX		\" start example
25.ta 1i 2i 3i 4i 5i 6i
26.PP
27.RS 
28.PD 0
29.ft 5
30.nf
31..
32.de EE		\" end example
33.fi
34.ft
35.PD
36.RE
37.PP
38..
39.TH TM 3
40.SH NAME
41tm \- time conversion support
42.SH SYNOPSIS
43.L "#include <tm.h>"
44.SH DESCRIPTION
45The
46.I tm
47library supports conversion between
48string date specifications,
49.L time_t
50clock values and
51.L "struct tm"
52values.
53.L localtime()
54and
55.L gmtime()
56(see
57.IR ctime (3))
58are used to determine local time zone information.
59.PP
60.L time_t
61values are the number of seconds since the epoch,
62.BR "Jan 1 00:00:00 GMT 1970" ,
63with leap seconds omitted.
64.PP
65The global variable
66.L "int tm_info.flags"
67contains flags that allow all programs using the library
68to be controlled in a consistent manner.
69.L tm_info.flags
70is initialized by the
71.L tminit()
72routine described below, and may be explicitly reset after
73.L tminit()
74is called.
75The flags are:
76.TP
77.L TM_ADJUST
78Set by
79.L tminit()
80if
81.L localtime()
82and
83.L gmtime()
84do not compensate for leap seconds.
85.TP
86.L TM_LEAP
87.L time_t
88values are interpreted as if they include leap seconds.
89Set by
90.L tminit()
91if the
92.L leap
93option is set in the
94.L TM_OPTIONS
95environment variable.
96.TP
97.L TM_UTC
98Times are relative to
99.B UTC
100(universal coordinated time, i.e.,
101.BR GMT ).
102Otherwise times are relative to the local time zone.
103Set by
104.L tminit()
105if the time zone name matches one of
106.L tm_info.format[43]
107through
108.L tm_info.format[46]
109described below.
110If the time zone name is not determined by
111.L localtime()
112then the environment variables
113.L TZNAME
114(as described in BSD 4.3) and
115.L TZ
116(as described in System V)
117are checked, in order.
118If this fails then the time zone name is constructed using
119the local time zone offset.
120.PP
121The routines are:
122.TP
123.L "time_t tmdate(const char* date, char** end, time_t* clock)"
124Parses the date specification
125.L date
126using the
127.L tm_info.format
128string table (described below)
129and returns the equivalent
130.L time_t
131value.
132If
133.RL non- NULL ,
134.L end
135is set to the position of the first unrecognized character in
136.LR date .
137.L clock
138is used to provide default values for omitted components in
139.LR date .
140If
141.L clock
142is
143.L NULL
144then the current time is used.
145.TP
146.L "struct tm* tmfix(struct tm* tp)"
147Corrects any out of bounds fields in
148.L tp
149and returns
150.L tp
151as its value.
152The corrections start with
153.L tp->tm_sec
154and propagate down to
155.LR tp->tm_year .
156For example, if
157.L tp->tm_sec
158were 61 then it would change to 1 and
159.L tp->tm_min
160would be incremented by 1, and so on.
161.LR tp->tm_wday ,
162.LR tp->tm_yday
163and
164.L tp->tm_isdst
165are not changed as these can be computed from the other fields.
166.TP
167.L "char* tmfmt(char* buf, size_t len, const char* format, time_t* clock)"
168Formats the date pointed to by
169.L clock
170into the buffer
171.L buf
172with size
173.L len
174bytes according to the format specification
175.LR format .
176If
177.L format
178is
179.L NULL
180or empty then the string
181.L tm_info.format[40]
182is used.
183If
184.L clock
185is
186.L NULL
187then the current time is used.
188A pointer to the end of
189.L buf
190(i.e., the terminating
191.LR "'\e0'" )
192is returned.
193.RS
194.PP
195.L format
196is in the style of
197.IR printf (3),
198where
199.BI % field
200causes the corresponding fixed size field to be placed in
201.LR buf ,
202zero padded if necessary, and \e\fIc\fP and \e\fInnn\fP
203sequences are interpreted as in the C language.
204Otherwise invalid
205.BI % field
206specifications and all other characters in
207.L format
208are copied into
209.L buf
210without change.
211String field values are taken from the
212.L tm_info.format
213string table.
214The
215.I fields
216are:
217.TP
218.PD 0
219.B %
220.B %
221character.
222.TP
223.B a
224Abbreviated weekday name.
225.TP
226.B A
227Full weekday name.
228.TP
229.B b
230Abbreviated month name.
231.TP
232.B c
233.IR ctime (3)
234style date without the trailing
235.BR newline .
236.TP
237.B C
238.IR date (1)
239style date.
240.TP
241.B d
242Day of month number.
243.TP
244.B D
245Date as
246.IR mm / dd / yy .
247.TP
248.B e
249Blank padded day of month number.
250.TP
251.B E
252Unpadded day of month number.
253.TP
254.B h
255Abbreviated month name.
256.TP
257.B H
25824-hour clock hour.
259.TP
260.B i
261International
262.IR date (1)
263date that includes the time zone type name.
264.TP
265.B I
26612-hour clock hour.
267.TP
268.B j
2691-offset Julian date.
270.TP
271.B J
2720-offset Julian date.
273.TP
274.B l
275.IR ls (1)
276.B \-l
277date that lists recent dates with
278.IR hh : mm
279and distant dates with
280.IR yyyy .
281.TP
282.B m
283Month number.
284.TP
285.B M
286Minutes.
287.TP
288.B n
289.B newline
290character.
291.TP
292.B p
293Meridian (e.g.,
294.B AM
295or
296.BR PM ).
297.TP
298.B r
29912-hour time as
300.IR hh : mm : ss
301.IR meridian .
302.TP
303.B R
30424-hour time as
305.IR hh : mm .
306.TP
307.B S
308Seconds.
309.TP
310.B t
311.B tab
312character.
313.TP
314.B T
31524-hour time as
316.IR hh : mm : ss .
317.TP
318.B U
319Week number with Sunday as the first day.
320.TP
321.B w
322Weekday number.
323.TP
324.B W
325Week number with Monday as the first day.
326.TP
327.B x
328Local date style, using
329.LR tm_info.format[39] ,
330that includes the month, day and year.
331.TP
332.B X
333Local time style, using
334.LR tm_info.format[38] ,
335that includes the hours and minutes.
336.TP
337.B y
3382-digit year.
339.TP
340.B Y
3414-digit year.
342.TP
343.B z
344Time zone type name.
345.TP
346.B Z
347Time zone name.
348.TP
349.BI + flag
350.TP
351.BI \- flag
352Temporarily (until
353.L tmform()
354returns) sets (+) or clears (\-) the
355.L tm_info.flags
356flags specified by
357.IR flag :
358.RS
359.TP
360.B l
361.L TM_LEAP
362.TP
363.B u
364.L TM_UTC
365.RE
366.TP
367.B #
368Number of seconds since the epoch.
369.PD
370.RE
371.TP
372.L "void tminit(Tm_zone_t* zone)"
373Implicitly called by the other
374.I tm
375library routines to initialize global data, including the
376.L tm_info.format
377table and the
378.L tm_info.flags
379global flags.
380Global data should only be modified after an explicit call to
381.LR tminit .
382If
383.L "zone != 0"
384then it specifies a time zone other that the local time zone.
385.TP
386.L "void tmset(Tm_zone_t* zone);"
387.L tmset
388sets the reference timezoe to
389.LR zone .
390.L tm_info.local 
391points to the local timezone and
392.L tm_info.zone
393points to the current reference timezone.
394.TP
395.L "time_t tmleap(time_t* clock)"
396Returns a
397.L time_t
398value for the time pointed to by
399.L clock
400with leap seconds adjusted for external
401routines that do not handle leap seconds.
402If
403.L clock
404is
405.L NULL
406then the current time is used.
407Adjustments are only done if the
408.L TM_ADJUST
409flag is set in
410.LR tm_info.flags .
411.TP
412.L "struct tm* tmmake(time_t* clock)"
413Returns a pointer to the
414.L tm
415struct corresponding to the time pointed to by
416.LR clock .
417If
418.L clock
419is
420.L NULL
421then the current time is used.
422.TP
423.L "time_t tmtime(struct tm* tp, int west)"
424Returns the
425.L time_t
426value corresponding to
427.LR tp .
428If
429.L west
430is
431.L TM_LOCALZONE
432then
433.L tm
434is relative to the local time zone,
435otherwise
436.L west
437is the number of minutes west of
438.B UTC
439with daylight savings time taken into account.
440.LR tp->tm_wday ,
441.LR tp->tm_yday
442and
443.L tp->tm_isdst
444are ignored in the conversion.
445.PP
446The library routines use a table of date strings pointed to by
447.LR "char** tm_info.format" .
448The indices in
449.L tm_info.format
450are fixed by category.
451.L tm_info.format
452may be changed to point to other tables
453according to local language and date conventions.
454The contents by index (showing the USA English values) are:
455.RS
456.TP
457.PD 0
458.B 0-11
4593-character abbreviated month names.
460.TP
461.B 12-23
462Full month names.
463.TP
464.B 24-30
4653-character abbreviated weekday names.
466.TP
467.B 31-37
468Full weekday names.
469.TP
470.B 38
471.L tmform()
472local time format used by the
473.B %X
474field.
475.TP
476.B 39
477.L tmform()
478local date format used by the
479.B %x
480field.
481.TP
482.B 40
483.L tmform()
484format used if the
485.L format
486argument is
487.L NULL
488or empty.
489.TP
490.B 41-42
491Meridian names: AM, PM.
492.TP
493.B 43-46
494.B UTC
495time zone names: GMT, UTC, UCT, CUT.
496.TP
497.B 47-50
498Daylight savings time suffix names: DST.
499.TP
500.B 51-54
501Suffixes to be ignored when matching strings in
502.LR tmform() .
503.TP
504.B 55-61
505Time part names: second, hour, minute, day, week, month, year.
506.TP
507.B 62-65
508Hours of the day names: midnight, morning, noon, evening.
509.TP
510.B 66-68
511Relative day names: yesterday, today, tomorrow.
512.TP
513.B 69-71
514Past relative time references: last, ago, past.
515.TP
516.B 72-75
517Current relative time references: this, now, current.
518.TP
519.B 75-77
520Future relative time references: next, hence, coming.
521.TP
522.B 78-80
523Exact relative time references: exactly.
524.TP
525.B 81-85
526Noise words to be ignored: at, in, on.
527.PD
528.RE
529.PP
530Low level support functions and data are described in
531.LR <tm.h> .
532.SH EXAMPLES
533.EX
534#include <tm.h>
535main() {
536    int       i;
537    time_t    t;
538    char      buf[128];
539    struct {
540        char* date;
541        char* format;
542    }         x[] = {
543        "now",                 "%i",
544        "2 months ago",        "%C",
545        "this Wednesday noon", "%x %I:%M %p",
546        "last December 25",    "%A",
547        0,                     0
548    };
549    for (i = 0; x[i].date; i++) {
550        t = tmdate(x[i].date, (char*)0, (time_t*)0);
551        (void)tmform(buf, x[i].format, &t);
552        puts(buf);
553    }
554}
555.EE
556produces
557.EX
558Fri Sep 30 12:10:14 USA EDT 1988
559Fri Jul  1 00:00:00 EDT 1988
56010/05/88 12:00 PM
561Friday
562.EE
563.SH "SEE ALSO"
564date(1), time(2), ctime(3)
565.SH BUGS
566.L "struct tm"
567values may get clobbered by the
568.I tm
569library routines as the
570.IR ctime (3)
571routines typically return pointers to a single static
572.L "struct tm"
573area.
574.L tmdate()
575uses an internal international time zone name table that will
576probably always be incomplete.
577