fdate - format date specification

#include <sys/types.h>
#include <sys/time.h>

char *fdate(buffer,format,tm)
char *buffer, *format;
struct tm *tm;

Fdate formats the information supplied in a tm structure into an
ASCII date specification. The formatting is controlled by the
format string (described below). The result is stored in buffer,
and a pointer to it returned as the function value. Buffer should
be pre-allocated to be large enough for the result string.

This section describes the format specification options which may
be used in the format string. These patterns resemble those used
by printf(3).

The percent sign indicates that a field of the tm structure is to
be inserted into the result at that point. The fields are named as

%wday name of the week day
%day number of the month day
%month name of the month
%nmonth number of the month
%year year
%yday number of the day within the year
%hour hour of the day
%min minutes
%sec seconds
%noon generates the word "noon" at noon, fails otherwise
%midnight generates "00:00" at midnight, fails otherwise
%am generates "am" or "pm" as appropriate
%time generates the time in a format explained below
%th st, nd, rd or th as appropriate.

Simply naming the field will insert it in the result. Thus,

"Today is %wday"

will result in

"Today is tuesday"

on Tuesday. Of course, it would be better if the weekday was
indicated with a capital letter. The alphabetic fields are
capitalized in the same manner as the field was named, so %Wday
inserts Tuesday and %WDAY inserts TUESDAY.

You can also specify variable formats, allowing the format of the
result to vary depending on the date/time being formatted. This is
done by surrounding part of the format string in braces or square
brackets. If a format string is enclosed in braces, then the
entire string will produce no result if any field enclosed within
the braces itself failed to produce a result. A field will fail to
produce a result if it is unspecified in the date and cannot be
computed from the date (e.g. when the time is not specified).

Thus, for example, in the format string,

"hello {how are you %sec %min} goodbye"

the result will be simply

"hello goodbye"

if either seconds or minutes are undefined. Otherwise, it will
result in something like

"hello how are you 34 23 goodbye".

Square brackets function almost identically, except that the entire
string is not inserted only if all of the fields are undefined.

"hello [how are you %sec %min] goodbye"

will result in

"hello goodbye"

if both seconds and minutes are undefined, but will otherwise
insert the middle part as well.

Within brackets, alternatives can be specified by separating them
with vertical bars ("|"). The first alternative to succeed is the
one that is used.

While %field generally gives the value of the field, %?field may be
used to query the nature of the field; if it has a reasonable
default value, then the field fails. Reasonable defaults are zero
for the minutes and seconds, and the current year.

Additionally, a numeric field width may be specified between the %
and the field name. If the field width begins with a zero, the
field will be inserted with leading zeroes. For the hour field, a
leading zero also serves to indicate 24-hour notation.

As a simple case, the format string

"Today is the %yday%th day of %year."

will result in something like

"Today is the 101st day of 1987."


"%3Wday %2day %3Month %year %0hour:%min:%sec %yday"

will result in something like

"Sat 7 Apr 1984 16:32:00 97"

As a final, more complex example, if the format given is:


This will insert "00:00" if it is midnight, or "noon" if it is
noon. Otherwise, if the seconds are defined it will insert the
hour (in 24-hour format because of the field width zero), minute,
and second, separated by colons. If the seconds are not defined or
are equal to zero, it will insert the hour (in 12 hour format), the
minutes if they are defined (omitting the relevant colon if they
aren’t defined), and "am" or "pm". This format, incidentally, is
precisely what you can get with the rather simpler field "%time".

time(2), ctime(3), gtime(3), localtime(3), parsedate(3)

There are no error conditions. An invalid field name will be
treated as literal text.