Date and time (time.h)¶
Include time.h for calendar types, clock access, broken-down
time conversion, and fixed-C-locale formatting.
Types and Macros¶
| Name | Meaning |
|---|---|
clock_t |
Processor time type; same width as long on this target. |
time_t |
Signed 32-bit calendar time type; same representation as long. |
CLOCKS_PER_SEC |
clock() ticks per second. CP/M 2.2 has no clock; clock() returns -1. |
struct tm |
Broken-down calendar time. |
struct tm contains the standard C89 fields. DCC uses 16-bit int members,
32-bit time_t and clock_t, and no timezone extension fields.
Functions¶
| Function | Summary |
|---|---|
char *asctime(const struct tm *tp) |
Convert *tp to a string of the form "Www Mmm dd hh:mm:ss yyyy\n" in an internal 26-byte static buffer (not reentrant). Returns NULL without modifying that buffer if tp is NULL, weekday/month is out of range, any numeric clock/date field is outside its struct tm range, or the actual year is outside 0000..9999. |
clock_t clock(void) |
Processor time used since program start; returns (clock_t)-1 (unavailable on CP/M 2.2). |
char *ctime(const time_t *tp) |
Equivalent to asctime(localtime(tp)). Returns NULL if tp is NULL. |
float difftime(time_t t1, time_t t0) |
Difference t1-t0 as a floating-point count of seconds. The subtraction is evaluated without signed-long overflow before rounding the mathematical result to the target's single-precision float. Note: C89 returns double; dcc returns float (no double type). |
struct tm *gmtime(const time_t *tp) |
Convert tp to broken-down time in an internal static buffer (not reentrant). Returns NULL if tp is NULL or tp is negative; time_t bit patterns 0x80000000 through 0xffffffff are therefore rejected. |
struct tm *localtime(const time_t *tp) |
Identical to gmtime(tp): this target has no timezone database, so the BDOS clock's raw reading already is "local" time, with no UTC offset to apply (see time()'s own comment above). |
time_t mktime(struct tm *tp) |
Convert broken-down time tp (year/mon/mday/hour/min/sec) to a time_t, and normalize tp in place. All six input fields may be out of range and are combined before the representability check, so e.g. 1969-12-32 becomes 1970-01-01. tm_wday/tm_yday are always recomputed. Returns (time_t)-1 and leaves *tp byte-for-byte unchanged for NULL, a normalized pre-1970 value, or any value after the signed 32-bit maximum (including 2106-era unsigned bit patterns and values that would wrap modulo 2^32). It does not modify the shared object previously returned by gmtime/localtime when tp points to an unrelated object. |
size_t strftime(char *s, size_t max, const char *fmt, const struct tm *tp) |
Format broken-down time in the fixed C locale. |
time_t time(time_t *tp) |
Current calendar time; stores through tp if non-null. Reads a real clock via BDOS function 105 (CP/M 3+ "Get Date and Time") when the underlying system/emulator implements it - many do even while still reporting CP/M 2.2 via BDOS 12. The result tracks the BDOS clock's raw wall-clock reading with no timezone adjustment (CP/M has no timezone concept), encoded as a Unix time_t. Returns (time_t)-1, and stores -1 through tp, when the underlying BDOS doesn't actually implement the call (e.g. real CP/M 2.2 hardware), supplies invalid packed BCD, or reports a value after 2038-01-19 03:14:07. CP/M day 1 is 1978-01-01; the runtime's conversion therefore maps CP/M day 0 to Unix day 2921 (1977-12-31). |
Clock and calendar model¶
clock() returns (clock_t)-1: CP/M 2.2 has no processor-time service.
time() reads BDOS function 105 when the system or emulator implements it and
otherwise returns (time_t)-1. The result is the BDOS wall-clock reading
encoded as a signed Unix timestamp.
This is an epoch-based encoding of the BDOS clock fields, not a guarantee that
the clock is set to UTC. There is no timezone correction. The checked upper
limit is 2038-01-19 03:14:07; later timestamps or invalid clock fields return
(time_t)-1. If a non-NULL output pointer is supplied to time, the result,
including the failure value, is stored there too.
There is no timezone database. localtime() is therefore identical to
gmtime(), and %Z in strftime() expands to an empty string. asctime() and
the broken-down-time conversion functions use internal static storage. A later
gmtime() or localtime() call replaces their shared result, but mktime() on
an unrelated struct tm does not.
Fixed-C-locale strftime¶
strftime() supports every C89 conversion available from struct tm, plus
the %C century extension:
| Conversion | Fixed C-locale result |
|---|---|
%a, %A |
abbreviated or full weekday name |
%b, %B |
abbreviated or full month name |
%C |
calendar century (year / 100), at least two digits |
%c |
Www Mmm dd hh:mm:ss yyyy (space-padded one-digit day) |
%d, %H, %I, %j, %m, %M, %S |
zero-padded numeric fields |
%p |
AM or PM |
%U, %W |
Sunday-first or Monday-first week number |
%w |
weekday number, Sunday is zero |
%x |
mm/dd/yy |
%X |
hh:mm:ss |
%y, %Y |
two-digit or full year |
%Z |
empty string |
%% |
literal percent sign |
The locale is always "C"; no locale data is linked. tm_isdst is ignored,
and fields are not normalized or cross-checked against each other.
max == 0 returns zero without accessing any pointer. For a positive bound,
all pointers must be non-NULL and the range-bearing struct tm fields must be
valid. An unknown conversion or trailing % is rejected. Invalid input or an
insufficient destination returns zero and leaves the longest fitting prefix
NUL-terminated; a successful empty result also returns zero.