diff options
Diffstat (limited to 'libc/time')
-rw-r--r-- | libc/time/asctime.c | 64 | ||||
-rw-r--r-- | libc/time/asctime_r.c | 27 | ||||
-rw-r--r-- | libc/time/clock.c | 69 | ||||
-rw-r--r-- | libc/time/ctime.c | 52 | ||||
-rw-r--r-- | libc/time/ctime_r.c | 15 | ||||
-rw-r--r-- | libc/time/difftime.c | 44 | ||||
-rw-r--r-- | libc/time/gmtime.c | 67 | ||||
-rw-r--r-- | libc/time/gmtime_r.c | 17 | ||||
-rw-r--r-- | libc/time/lcltime.c | 57 | ||||
-rw-r--r-- | libc/time/lcltime_r.c | 104 | ||||
-rw-r--r-- | libc/time/mktime.c | 204 | ||||
-rw-r--r-- | libc/time/strftime.c | 444 | ||||
-rw-r--r-- | libc/time/time.c | 59 |
13 files changed, 1223 insertions, 0 deletions
diff --git a/libc/time/asctime.c b/libc/time/asctime.c new file mode 100644 index 0000000..4ad35e8 --- /dev/null +++ b/libc/time/asctime.c @@ -0,0 +1,64 @@ +/* + * asctime.c + * Original Author: G. Haley + * + * Converts the broken down time in the structure pointed to by tim_p into a + * string of the form + * + * Wed Jun 15 11:38:07 1988\n\0 + * + * Returns a pointer to the string. + */ + +/* +FUNCTION +<<asctime>>---format time as string + +INDEX + asctime +INDEX + _asctime_r + +ANSI_SYNOPSIS + #include <time.h> + char *asctime(const struct tm *<[clock]>); + char *asctime_r(const struct tm *<[clock]>, char *<[buf]>); + +TRAD_SYNOPSIS + #include <time.h> + char *asctime(<[clock]>) + struct tm *<[clock]>; + char *asctime_r(<[clock]>) + struct tm *<[clock]>; + char *<[buf]>; + +DESCRIPTION +Format the time value at <[clock]> into a string of the form +. Wed Jun 15 11:38:07 1988\n\0 +The string is generated in a static buffer; each call to <<asctime>> +overwrites the string generated by previous calls. + +RETURNS +A pointer to the string containing a formatted timestamp. + +PORTABILITY +ANSI C requires <<asctime>>. + +<<asctime>> requires no supporting OS subroutines. +*/ + +#include <time.h> +#include <_ansi.h> +#include <reent.h> + +#ifndef _REENT_ONLY + +char * +_DEFUN (asctime, (tim_p), + _CONST struct tm *tim_p) +{ + char *buf = _REENT->_new._reent._asctime_buf; + return asctime_r (tim_p, buf); +} + +#endif diff --git a/libc/time/asctime_r.c b/libc/time/asctime_r.c new file mode 100644 index 0000000..ff70ea4 --- /dev/null +++ b/libc/time/asctime_r.c @@ -0,0 +1,27 @@ +/* + * asctime_r.c + */ + +#include <stdio.h> +#include <time.h> + +char * +_DEFUN (asctime_r, (tim_p, result), + _CONST struct tm *tim_p _AND + char *result) +{ + static _CONST char day_name[7][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static _CONST char mon_name[12][3] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + sprintf (result, "%.3s %.3s %.2d %.2d:%.2d:%.2d %d\n", + day_name[tim_p->tm_wday], + mon_name[tim_p->tm_mon], + tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min, + tim_p->tm_sec, 1900 + tim_p->tm_year); + return result; +} diff --git a/libc/time/clock.c b/libc/time/clock.c new file mode 100644 index 0000000..b15915d --- /dev/null +++ b/libc/time/clock.c @@ -0,0 +1,69 @@ +/* NetWare can not use this implementation of clock, since it does not + have times or any similar function. It provides its own version of + clock in clib.nlm. If we can not use clib.nlm, then we must write + clock in sys/netware. */ + +#ifdef CLOCK_PROVIDED + +int _dummy_clock = 1; + +#else + +/* + * clock.c + * Original Author: G. Haley + * + * Determines the processor time used by the program since invocation. The time + * in seconds is the value returned divided by the value of the macro CLK_TCK. + * If the processor time used is not available, (clock_t) -1 is returned. + */ + +/* +FUNCTION +<<clock>>---cumulative processor time + +INDEX + clock + +ANSI_SYNOPSIS + #include <time.h> + clock_t clock(void); + +TRAD_SYNOPSIS + #include <time.h> + clock_t clock(); + +DESCRIPTION +Calculates the best available approximation of the cumulative amount +of time used by your program since it started. To convert the result +into seconds, divide by the macro <<CLOCKS_PER_SEC>>. + +RETURNS +The amount of processor time used so far by your program, in units +defined by the machine-dependent macro <<CLOCKS_PER_SEC>>. If no +measurement is available, the result is <<-1>>. + +PORTABILITY +ANSI C requires <<clock>> and <<CLOCKS_PER_SEC>>. + +Supporting OS subroutine required: <<times>>. +*/ + +#include <time.h> +#include <sys/times.h> +#include <reent.h> + +clock_t +clock () +{ + struct tms tim_s; + clock_t res; + + if ((res = (clock_t) _times_r (_REENT, &tim_s)) != -1) + res = (clock_t) (tim_s.tms_utime + tim_s.tms_stime + + tim_s.tms_cutime + tim_s.tms_cstime); + + return res; +} + +#endif /* CLOCK_PROVIDED */ diff --git a/libc/time/ctime.c b/libc/time/ctime.c new file mode 100644 index 0000000..e8ccc14 --- /dev/null +++ b/libc/time/ctime.c @@ -0,0 +1,52 @@ +/* + * ctime.c + * Original Author: G. Haley + */ + +/* +FUNCTION +<<ctime>>---convert time to local and format as string + +INDEX + ctime + +ANSI_SYNOPSIS + #include <time.h> + char *ctime(time_t <[clock]>); + char *ctime_r(time_t <[clock]>, char *<[buf]>); + +TRAD_SYNOPSIS + #include <time.h> + char *ctime(<[clock]>) + time_t <[clock]>; + char *ctime_r(<[clock]>, <[buf]>) + time_t <[clock]>; + char *<[buf]>; + +DESCRIPTION +Convert the time value at <[clock]> to local time (like <<localtime>>) +and format it into a string of the form +. Wed Jun 15 11:38:07 1988\n\0 +(like <<asctime>>). + +RETURNS +A pointer to the string containing a formatted timestamp. + +PORTABILITY +ANSI C requires <<ctime>>. + +<<ctime>> requires no supporting OS subroutines. +*/ + +#include <time.h> + +#ifndef _REENT_ONLY + +char * +_DEFUN (ctime, (tim_p), + _CONST time_t * tim_p) +{ + return asctime (localtime (tim_p)); +} + +#endif diff --git a/libc/time/ctime_r.c b/libc/time/ctime_r.c new file mode 100644 index 0000000..fda8cac --- /dev/null +++ b/libc/time/ctime_r.c @@ -0,0 +1,15 @@ +/* + * ctime_r.c + */ + +#include <time.h> + +char * +_DEFUN (ctime_r, (tim_p, result), + _CONST time_t * tim_p _AND + char * result) + +{ + struct tm tm; + return asctime_r (localtime_r (tim_p, &tm), result); +} diff --git a/libc/time/difftime.c b/libc/time/difftime.c new file mode 100644 index 0000000..93a4f00 --- /dev/null +++ b/libc/time/difftime.c @@ -0,0 +1,44 @@ +/* + * difftime.c + * Original Author: G. Haley + */ + +/* +FUNCTION +<<difftime>>---subtract two times + +INDEX + difftime + +ANSI_SYNOPSIS + #include <time.h> + double difftime(time_t <[tim1]>, time_t <[tim2]>); + +TRAD_SYNOPSIS + #include <time.h> + double difftime(<[tim1]>, <[tim2]>) + time_t <[tim1]>; + time_t <[tim2]>; + +DESCRIPTION +Subtracts the two times in the arguments: `<<<[tim1]> - <[tim2]>>>'. + +RETURNS +The difference (in seconds) between <[tim2]> and <[tim1]>, as a <<double>>. + +PORTABILITY +ANSI C requires <<difftime>>, and defines its result to be in seconds +in all implementations. + +<<difftime>> requires no supporting OS subroutines. +*/ + +#include <time.h> + +double +_DEFUN (difftime, (tim1, tim2), + time_t tim1 _AND + time_t tim2) +{ + return ((double) tim1 - tim2); +} diff --git a/libc/time/gmtime.c b/libc/time/gmtime.c new file mode 100644 index 0000000..4f5bbe4 --- /dev/null +++ b/libc/time/gmtime.c @@ -0,0 +1,67 @@ +/* + * gmtime.c + * Original Author: G. Haley + * + * Converts the calendar time pointed to by tim_p into a broken-down time + * expressed as Greenwich Mean Time (GMT). Returns a pointer to a structure + * containing the broken-down time, or a null pointer if GMT is not + * available. + */ + +/* +FUNCTION +<<gmtime>>---convert time to UTC traditional form + +INDEX + gmtime + +ANSI_SYNOPSIS + #include <time.h> + struct tm *gmtime(const time_t *<[clock]>); + struct tm *gmtime_r(const time_t *<[clock]>, struct tm *<[res]>); + +TRAD_SYNOPSIS + #include <time.h> + struct tm *gmtime(<[clock]>) + const time_t *<[clock]>; + struct tm *gmtime_r(<[clock]>, <[res]>) + const time_t *<[clock]>; + struct tm *<[res]>; + +DESCRIPTION +<<gmtime>> assumes the time at <[clock]> represents a local time. +<<gmtime>> converts it to UTC (Universal Coordinated Time, also known in some +countries as GMT, Greenwich Mean time), then converts the +representation from the arithmetic representation to +the traditional representation defined by <<struct tm>>. + +<<gmtime>> constructs the traditional time representation in static +storage; each call to <<gmtime>> or <<localtime>> will overwrite the +information generated by previous calls to either function. + +RETURNS +A pointer to the traditional time representation (<<struct tm>>). + +PORTABILITY +ANSI C requires <<gmtime>>. + +<<gmtime>> requires no supporting OS subroutines. +*/ + +#include <stdlib.h> +#include <time.h> + +#define _GMT_OFFSET 0 + +#ifndef _REENT_ONLY + +struct tm * +_DEFUN (gmtime, (tim_p), + _CONST time_t * tim_p) +{ + time_t tim = *tim_p + _GMT_OFFSET; + + return (localtime (&tim)); +} + +#endif diff --git a/libc/time/gmtime_r.c b/libc/time/gmtime_r.c new file mode 100644 index 0000000..7afa021 --- /dev/null +++ b/libc/time/gmtime_r.c @@ -0,0 +1,17 @@ +/* + * gmtime_r.c + */ + +#include <time.h> + +#define _GMT_OFFSET 0 + +struct tm * +_DEFUN (gmtime_r, (tim_p, res), + _CONST time_t * tim_p _AND + struct tm *res) +{ + time_t tim = *tim_p + _GMT_OFFSET; + + return (localtime_r (&tim, res)); +} diff --git a/libc/time/lcltime.c b/libc/time/lcltime.c new file mode 100644 index 0000000..d4c7d7d --- /dev/null +++ b/libc/time/lcltime.c @@ -0,0 +1,57 @@ +/* + * localtime.c + */ + +/* +FUNCTION +<<localtime>>---convert time to local representation + +INDEX + localtime + +ANSI_SYNOPSIS + #include <time.h> + struct tm *localtime(time_t *<[clock]>); + struct tm *localtime_r(time_t *<[clock]>, struct tm *<[res]>); + +TRAD_SYNOPSIS + #include <time.h> + struct tm *localtime(<[clock]>) + time_t *<[clock]>; + struct tm *localtime(<[clock]>, <[res]>) + time_t *<[clock]>; + struct tm *<[res]>; + +DESCRIPTION +<<localtime>> converts the time at <[clock]> into local time, then +converts its representation from the arithmetic representation to the +traditional representation defined by <<struct tm>>. + +<<localtime>> constructs the traditional time representation in static +storage; each call to <<gmtime>> or <<localtime>> will overwrite the +information generated by previous calls to either function. + +<<mktime>> is the inverse of <<localtime>>. + +RETURNS +A pointer to the traditional time representation (<<struct tm>>). + +PORTABILITY +ANSI C requires <<localtime>>. + +<<localtime>> requires no supporting OS subroutines. +*/ + +#include <time.h> +#include <reent.h> + +#ifndef _REENT_ONLY + +struct tm * +_DEFUN (localtime, (tim_p), + _CONST time_t * tim_p) +{ + return localtime_r (tim_p, &(_REENT->_new._reent._localtime_buf)); +} + +#endif diff --git a/libc/time/lcltime_r.c b/libc/time/lcltime_r.c new file mode 100644 index 0000000..1b4269e --- /dev/null +++ b/libc/time/lcltime_r.c @@ -0,0 +1,104 @@ +/* + * localtime_r.c + * Original Author: Adapted from tzcode maintained by Arthur David Olson. + * + * Converts the calendar time pointed to by tim_p into a broken-down time + * expressed as local time. Returns a pointer to a structure containing the + * broken-down time. + */ + +#include <stdlib.h> +#include <time.h> + +#define SECSPERMIN 60L +#define MINSPERHOUR 60L +#define HOURSPERDAY 24L +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) +#define DAYSPERWEEK 7 +#define MONSPERYEAR 12 + +#define YEAR_BASE 1900 +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY 4 + +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) + +static _CONST int mon_lengths[2][MONSPERYEAR] = { + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +} ; + +static _CONST int year_lengths[2] = { + 365, + 366 +} ; + +struct tm * +_DEFUN (localtime_r, (tim_p, res), + _CONST time_t * tim_p _AND + struct tm *res) +{ + long days, rem; + int y; + int yleap; + _CONST int *ip; + + days = ((long) *tim_p) / SECSPERDAY; + rem = ((long) *tim_p) % SECSPERDAY; + while (rem < 0) + { + rem += SECSPERDAY; + --days; + } + while (rem >= SECSPERDAY) + { + rem -= SECSPERDAY; + ++days; + } + + /* compute hour, min, and sec */ + res->tm_hour = (int) (rem / SECSPERHOUR); + rem %= SECSPERHOUR; + res->tm_min = (int) (rem / SECSPERMIN); + res->tm_sec = (int) (rem % SECSPERMIN); + + /* compute day of week */ + if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0) + res->tm_wday += DAYSPERWEEK; + + /* compute year & day of year */ + y = EPOCH_YEAR; + if (days >= 0) + { + for (;;) + { + yleap = isleap(y); + if (days < year_lengths[yleap]) + break; + y++; + days -= year_lengths[yleap]; + } + } + else + { + do + { + --y; + yleap = isleap(y); + days += year_lengths[yleap]; + } while (days < 0); + } + + res->tm_year = y - YEAR_BASE; + res->tm_yday = days; + ip = mon_lengths[yleap]; + for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon) + days -= ip[res->tm_mon]; + res->tm_mday = days + 1; + + /* set daylight saving time flag */ + res->tm_isdst = -1; + + return (res); +} diff --git a/libc/time/mktime.c b/libc/time/mktime.c new file mode 100644 index 0000000..431eca5 --- /dev/null +++ b/libc/time/mktime.c @@ -0,0 +1,204 @@ +/* + * mktime.c + * Original Author: G. Haley + * + * Converts the broken-down time, expressed as local time, in the structure + * pointed to by tim_p into a calendar time value. The original values of the + * tm_wday and tm_yday fields of the structure are ignored, and the original + * values of the other fields have no restrictions. On successful completion + * the fields of the structure are set to represent the specified calendar + * time. Returns the specified calendar time. If the calendar time can not be + * represented, returns the value (time_t) -1. + */ + +/* +FUNCTION +<<mktime>>---convert time to arithmetic representation + +INDEX + mktime + +ANSI_SYNOPSIS + #include <time.h> + time_t mktime(struct tm *<[timp]>); + +TRAD_SYNOPSIS + #include <time.h> + time_t mktime(<[timp]>) + struct tm *<[timp]>; + +DESCRIPTION +<<mktime>> assumes the time at <[timp]> is a local time, and converts +its representation from the traditional representation defined by +<<struct tm>> into a representation suitable for arithmetic. + +<<localtime>> is the inverse of <<mktime>>. + +RETURNS +If the contents of the structure at <[timp]> do not form a valid +calendar time representation, the result is <<-1>>. Otherwise, the +result is the time, converted to a <<time_t>> value. + +PORTABILITY +ANSI C requires <<mktime>>. + +<<mktime>> requires no supporting OS subroutines. +*/ + +#include <stdlib.h> +#include <time.h> + +#define _SEC_IN_MINUTE 60 +#define _SEC_IN_HOUR 3600 +#define _SEC_IN_DAY 86400 + +static _CONST int DAYS_IN_MONTH[12] = +{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x]) + +static _CONST int _DAYS_BEFORE_MONTH[12] = +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + +#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0)) +#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365) + +static void +validate_structure (tim_p) + struct tm *tim_p; +{ + div_t res; + int days_in_feb = 28; + + /* calculate time & date to account for out of range values */ + if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59) + { + res = div (tim_p->tm_sec, 60); + tim_p->tm_min += res.quot; + if ((tim_p->tm_sec = res.rem) < 0) + { + tim_p->tm_sec += 60; + --tim_p->tm_min; + } + } + + if (tim_p->tm_min < 0 || tim_p->tm_min > 59) + { + res = div (tim_p->tm_min, 60); + tim_p->tm_hour += res.quot; + if ((tim_p->tm_min = res.rem) < 0) + { + tim_p->tm_min += 60; + --tim_p->tm_hour; + } + } + + if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23) + { + res = div (tim_p->tm_hour, 24); + tim_p->tm_mday += res.quot; + if ((tim_p->tm_hour = res.rem) < 0) + { + tim_p->tm_hour += 24; + --tim_p->tm_mday; + } + } + + if (tim_p->tm_mon > 11) + { + res = div (tim_p->tm_mon, 12); + tim_p->tm_year += res.quot; + if ((tim_p->tm_mon = res.rem) < 0) + { + tim_p->tm_mon += 12; + --tim_p->tm_year; + } + } + + if (_DAYS_IN_YEAR (tim_p->tm_year) == 366) + days_in_feb = 29; + + if (tim_p->tm_mday <= 0) + { + while (tim_p->tm_mday <= 0) + { + if (--tim_p->tm_mon == -1) + { + tim_p->tm_year--; + tim_p->tm_mon = 11; + days_in_feb = + ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? + 29 : 28); + } + tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon); + } + } + else + { + while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon)) + { + tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon); + if (++tim_p->tm_mon == 12) + { + tim_p->tm_year++; + tim_p->tm_mon = 0; + days_in_feb = + ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? + 29 : 28); + } + } + } +} + +time_t +mktime (tim_p) + struct tm *tim_p; +{ + time_t tim = 0; + long days = 0; + int year; + + /* validate structure */ + validate_structure (tim_p); + + /* compute hours, minutes, seconds */ + tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) + + (tim_p->tm_hour * _SEC_IN_HOUR); + + /* compute days in year */ + days += tim_p->tm_mday - 1; + days += _DAYS_BEFORE_MONTH[tim_p->tm_mon]; + if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366) + days++; + + /* compute day of the year */ + tim_p->tm_yday = days; + + if (tim_p->tm_year > 10000 + || tim_p->tm_year < -10000) + { + return (time_t) -1; + } + + /* compute days in other years */ + if (tim_p->tm_year > 70) + { + for (year = 70; year < tim_p->tm_year; year++) + days += _DAYS_IN_YEAR (year); + } + else if (tim_p->tm_year < 70) + { + for (year = 69; year > tim_p->tm_year; year--) + days -= _DAYS_IN_YEAR (year); + days -= _DAYS_IN_YEAR (year); + } + + /* compute day of the week */ + if ((tim_p->tm_wday = (days + 4) % 7) < 0) + tim_p->tm_wday += 7; + + /* compute total seconds */ + tim += (days * _SEC_IN_DAY); + + return tim; +} diff --git a/libc/time/strftime.c b/libc/time/strftime.c new file mode 100644 index 0000000..1e6154f --- /dev/null +++ b/libc/time/strftime.c @@ -0,0 +1,444 @@ +/* + * strftime.c + * Original Author: G. Haley + * + * Places characters into the array pointed to by s as controlled by the string + * pointed to by format. If the total number of resulting characters including + * the terminating null character is not more than maxsize, returns the number + * of characters placed into the array pointed to by s (not including the + * terminating null character); otherwise zero is returned and the contents of + * the array indeterminate. + */ + +/* +FUNCTION +<<strftime>>---flexible calendar time formatter + +INDEX + strftime + +ANSI_SYNOPSIS + #include <time.h> + size_t strftime(char *<[s]>, size_t <[maxsize]>, + const char *<[format]>, const struct tm *<[timp]>); + +TRAD_SYNOPSIS + #include <time.h> + size_t strftime(<[s]>, <[maxsize]>, <[format]>, <[timp]>) + char *<[s]>; + size_t <[maxsize]>; + char *<[format]>; + struct tm *<[timp]>; + +DESCRIPTION +<<strftime>> converts a <<struct tm>> representation of the time (at +<[timp]>) into a string, starting at <[s]> and occupying no more than +<[maxsize]> characters. + +You control the format of the output using the string at <[format]>. +<<*<[format]>>> can contain two kinds of specifications: text to be +copied literally into the formatted string, and time conversion +specifications. Time conversion specifications are two-character +sequences beginning with `<<%>>' (use `<<%%>>' to include a percent +sign in the output). Each defined conversion specification selects a +field of calendar time data from <<*<[timp]>>>, and converts it to a +string in one of the following ways: + +o+ +o %a +An abbreviation for the day of the week. + +o %A +The full name for the day of the week. + +o %b +An abbreviation for the month name. + +o %B +The full name of the month. + +o %c +A string representing the complete date and time, in the form +. Mon Apr 01 13:13:13 1992 + +o %d +The day of the month, formatted with two digits. + +o %H +The hour (on a 24-hour clock), formatted with two digits. + +o %I +The hour (on a 12-hour clock), formatted with two digits. + +o %j +The count of days in the year, formatted with three digits +(from `<<001>>' to `<<366>>'). + +o %m +The month number, formatted with two digits. + +o %M +The minute, formatted with two digits. + +o %p +Either `<<AM>>' or `<<PM>>' as appropriate. + +o %S +The second, formatted with two digits. + +o %U +The week number, formatted with two digits (from `<<00>>' to `<<53>>'; +week number 1 is taken as beginning with the first Sunday in a year). +See also <<%W>>. + +o %w +A single digit representing the day of the week: Sunday is day <<0>>. + +o %W +Another version of the week number: like `<<%U>>', but counting week 1 +as beginning with the first Monday in a year. + +o +o %x +A string representing the complete date, in a format like +. Mon Apr 01 1992 + +o %X +A string representing the full time of day (hours, minutes, and +seconds), in a format like +. 13:13:13 + +o %y +The last two digits of the year. + +o %Y +The full year, formatted with four digits to include the century. + +o %Z +Defined by ANSI C as eliciting the time zone if available; it is not +available in this implementation (which accepts `<<%Z>>' but generates +no output for it). + +o %% +A single character, `<<%>>'. +o- + +RETURNS +When the formatted time takes up no more than <[maxsize]> characters, +the result is the length of the formatted string. Otherwise, if the +formatting operation was abandoned due to lack of room, the result is +<<0>>, and the string starting at <[s]> corresponds to just those +parts of <<*<[format]>>> that could be completely filled in within the +<[maxsize]> limit. + +PORTABILITY +ANSI C requires <<strftime>>, but does not specify the contents of +<<*<[s]>>> when the formatted string would require more than +<[maxsize]> characters. + +<<strftime>> requires no supporting OS subroutines. +*/ + +#include <stddef.h> +#include <stdio.h> +#include <time.h> + +static _CONST int dname_len[7] = +{6, 6, 7, 9, 8, 6, 8}; + +static _CONST char *_CONST dname[7] = +{"Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"}; + +static _CONST int mname_len[12] = +{7, 8, 5, 5, 3, 4, 4, 6, 9, 7, 8, 8}; + +static _CONST char *_CONST mname[12] = +{"January", "February", "March", "April", + "May", "June", "July", "August", "September", "October", "November", + "December"}; + +size_t +_DEFUN (strftime, (s, maxsize, format, tim_p), + char *s _AND + size_t maxsize _AND + _CONST char *format _AND + _CONST struct tm *tim_p) +{ + size_t count = 0; + int i; + + for (;;) + { + while (*format && *format != '%') + { + if (count < maxsize - 1) + s[count++] = *format++; + else + return 0; + } + + if (*format == '\0') + break; + + format++; + switch (*format) + { + case 'a': + for (i = 0; i < 3; i++) + { + if (count < maxsize - 1) + s[count++] = + dname[tim_p->tm_wday][i]; + else + return 0; + } + break; + case 'A': + for (i = 0; i < dname_len[tim_p->tm_wday]; i++) + { + if (count < maxsize - 1) + s[count++] = + dname[tim_p->tm_wday][i]; + else + return 0; + } + break; + case 'b': + for (i = 0; i < 3; i++) + { + if (count < maxsize - 1) + s[count++] = + mname[tim_p->tm_mon][i]; + else + return 0; + } + break; + case 'B': + for (i = 0; i < mname_len[tim_p->tm_mon]; i++) + { + if (count < maxsize - 1) + s[count++] = + mname[tim_p->tm_mon][i]; + else + return 0; + } + break; + case 'c': + if (count < maxsize - 24) + { + for (i = 0; i < 3; i++) + s[count++] = + dname[tim_p->tm_wday][i]; + s[count++] = ' '; + for (i = 0; i < 3; i++) + s[count++] = + mname[tim_p->tm_mon][i]; + + sprintf (&s[count], + " %.2d %2.2d:%2.2d:%2.2d %.4d", + tim_p->tm_mday, tim_p->tm_hour, + tim_p->tm_min, + tim_p->tm_sec, 1900 + + tim_p->tm_year); + count += 17; + } + else + return 0; + break; + case 'd': + if (count < maxsize - 2) + { + sprintf (&s[count], "%.2d", + tim_p->tm_mday); + count += 2; + } + else + return 0; + break; + case 'H': + if (count < maxsize - 2) + { + sprintf (&s[count], "%2.2d", + tim_p->tm_hour); + count += 2; + } + else + return 0; + break; + case 'I': + if (count < maxsize - 2) + { + if (tim_p->tm_hour == 0 || + tim_p->tm_hour == 12) + { + s[count++] = '1'; + s[count++] = '2'; + } + else + { + sprintf (&s[count], "%.2d", + tim_p->tm_hour % 12); + count += 2; + } + } + else + return 0; + break; + case 'j': + if (count < maxsize - 3) + { + sprintf (&s[count], "%.3d", + tim_p->tm_yday + 1); + count += 3; + } + else + return 0; + break; + case 'm': + if (count < maxsize - 2) + { + sprintf (&s[count], "%.2d", + tim_p->tm_mon + 1); + count += 2; + } + else + return 0; + break; + case 'M': + if (count < maxsize - 2) + { + sprintf (&s[count], "%2.2d", + tim_p->tm_min); + count += 2; + } + else + return 0; + break; + case 'p': + if (count < maxsize - 2) + { + if (tim_p->tm_hour < 12) + s[count++] = 'A'; + else + s[count++] = 'P'; + + s[count++] = 'M'; + } + else + return 0; + break; + case 'S': + if (count < maxsize - 2) + { + sprintf (&s[count], "%2.2d", + tim_p->tm_sec); + count += 2; + } + else + return 0; + break; + case 'U': + if (count < maxsize - 2) + { + sprintf (&s[count], "%2.2d", + (tim_p->tm_yday + 7 - + tim_p->tm_wday) / 7); + count += 2; + } + else + return 0; + break; + case 'w': + if (count < maxsize - 1) + { + sprintf (&s[count], "%1.1d", + tim_p->tm_wday); + count++; + } + else + return 0; + break; + case 'W': + if (count < maxsize - 2) + { + sprintf (&s[count], "%2.2d", + (tim_p->tm_yday + ((8 - + tim_p->tm_wday) % 7)) / 7); + count += 2; + } + else + return 0; + break; + case 'x': + if (count < maxsize - 15) + { + for (i = 0; i < 3; i++) + s[count++] = + dname[tim_p->tm_wday][i]; + s[count++] = ' '; + for (i = 0; i < 3; i++) + s[count++] = + mname[tim_p->tm_mon][i]; + + sprintf (&s[count], + " %.2d %.4d", tim_p->tm_mday, + 1900 + tim_p->tm_year); + count += 8; + } + else + return 0; + break; + case 'X': + if (count < maxsize - 8) + { + sprintf (&s[count], + "%2.2d:%2.2d:%2.2d", + tim_p->tm_hour, tim_p->tm_min, + tim_p->tm_sec); + count += 8; + } + else + return 0; + break; + case 'y': + if (count < maxsize - 2) + { + /* The year could be greater than 100, so we need the value + modulo 100. The year could be negative, so we need to + correct for a possible negative remainder. */ + sprintf (&s[count], "%2.2d", + (tim_p->tm_year % 100 + 100) % 100); + count += 2; + } + else + return 0; + break; + case 'Y': + if (count < maxsize - 4) + { + sprintf (&s[count], "%.4d", + 1900 + tim_p->tm_year); + count += 4; + } + else + return 0; + break; + case 'Z': + break; + case '%': + if (count < maxsize - 1) + s[count++] = '%'; + else + return 0; + break; + } + if (*format) + format++; + else + break; + } + s[count] = '\0'; + + return count; +} diff --git a/libc/time/time.c b/libc/time/time.c new file mode 100644 index 0000000..38cce50 --- /dev/null +++ b/libc/time/time.c @@ -0,0 +1,59 @@ +/* FIXME: doc says "not avail" due to #if 0. + DELETE that line if inappropriate! */ +/* +FUNCTION +<<time>>---get current calendar time (as single number) + +INDEX + time + +ANSI_SYNOPSIS + #include <time.h> + time_t time(time_t *<[t]>); + +TRAD_SYNOPSIS + #include <time.h> + time_t time(<[t]>) + time_t *<[t]>; + +DESCRIPTION +<<time>> looks up the best available representation of the current +time and returns it, encoded as a <<time_t>>. It stores the same +value at <[t]> unless the argument is <<NULL>>. + +RETURNS +A <<-1>> result means the current time is not available; otherwise the +result represents the current time. + +PORTABILITY +ANSI C requires <<time>>. + +Supporting OS subroutine required: Some implementations require +<<gettimeofday>>. +*/ + +#ifdef HAVE_GETTIMEOFDAY + +/* Most times we have a system call in newlib/libc/sys/.. to do this job */ + +#include <_ansi.h> +#include <reent.h> +#include <sys/types.h> +#include <sys/time.h> + +time_t +_DEFUN (time, (t), + time_t * t) +{ + struct timeval now; + + if (_gettimeofday_r (_REENT, &now, (struct timezone *) 0) >= 0) + { + if (t) + *t = now.tv_sec; + return now.tv_sec; + } + return -1; +} + +#endif |