home *** CD-ROM | disk | FTP | other *** search
- #include "cutil.h"
-
- #include <ctype.h>
-
- /*
- strptime() converts the character string pointed to by buf
- to a time value, which is stored in the tm structure pointed
- to by tm, using the format specified by fmt. A pointer to
- the character following the last character in the string
- pointed to by buf is returned. fmt is a character string
- that consists of field descriptors and text characters, rem-
- iniscent of scanf(3v). Each field descriptor consists of a
- % character followd by another character that specifies the
- replacement for the field descriptor. All other characters
- are copied from fmt into the result. The following field
- descriptors are supported:
-
- %% same as %
-
- %a
- %A day of week, using locale's weekday names; either
- the abbreviated or full name may be specified
-
- %b
- %B
- %h month, using locale's month names; either the
- abbreviated or full name may be specified
-
- %c date and time as %x %X
-
- %C date and time, in locale's long-format date and
- time representation
-
- %d
- %e day of month (1-31; leading zeroes are permitted
- but not required)
-
- %D date as %m/%d/%y
-
- %H
- %k hour (0-23; leading zeroes are permitted but not
-
- required)
-
- %I
- %l hour (0-12; leading zeroes are permitted but not
- required)
-
- %j day number of year (001-366)
-
- %m month number (1-12; leading zeroes are permitted
- but not required)
-
- %M minute (0-59; leading zeroes are permitted but not
- required)
-
- %p locale's equivalent of AM or PM
-
- %r time as %I:%M:%S %p
-
- %R time as %H:%M
-
- %S seconds (0-59; leading zeroes are permitted but
- not required)
-
- %T time as %H:%M:%S
-
- %x date, using locale's date format
-
- %X time, using locale's time format
-
- %y year within century (0-99; leading zeroes are per-
- mitted but not required)
-
- %Y year, including century (for example, 1988)
-
- Case is ignored when matching items such as month or weekday
- names. The %M, %S, %y, and %Y fields are optional; if they
- would be matched by white space, the match is suppressed and
- the appropriate field of the tm structure pointed to by tm
- is left unchanged. If any of the format items %d, %e, %H,
- %k, %I, %l, %m, %M, %S, %y, or %Y are matched, but the
- string that matches them is followed by white space, all
- subsequent items in the format string are skipped up to
- white space or the end of the format. The net result is
- that, for example, the format %m/%d/%y can be matched by the
- string 12/31; the tm_mon and tm_mday fields of the tm struc-
- ture pointed to by tm will be set to 11 and 31, respec-
- tively, while the tm_year field will be unchanged.
-
- */
-
- /*
- struct tm {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday;
- int tm_mon;
- int tm_year;
- int tm_wday;
- int tm_yday;
- int tm_isdst;
- char *tm_zone;
- long tm_gmtoff;
- };
- */
-
- #define CHECK_FOR_SPACES(buf, fmt) \
- if ((buf == NULL) || isspace(*buf) || (*buf == '\0')) { \
- while ((! isspace(**fmt)) && (**fmt != '\0')) { \
- (*fmt)++; \
- } \
- (*fmt)--; \
- } \
- return(buf)
-
- static int substrmatch(char *, char *);
- static int substrmatch (str, match)
- char *str;
- char *match;
- {
- int match_len = 0;
-
- while ((*str != '\0') && (*match != '\0')) {
- if (tolower(*str) != tolower(*match)) {
- return(match_len);
- }
- str++;
- match++;
- match_len++;
- }
- return(match_len);
- } /* substrmatch() */
-
-
- static char *weekday_names[] = {
- "Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday"
- }; /* weekday_names[] */
-
- static char *month_names[] = {
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December"
- }; /* month_names[] */
-
- static char *get_weekday_name(char *, char **, struct tm *);
- static char *get_weekday_name (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int i;
- int len;
- int num = sizeof(weekday_names) / sizeof(weekday_names[0]);
-
- for (i = 0; i < num; i++) {
- len = substrmatch(buf, weekday_names[i]);
- if (len > 2) {
- tm->tm_wday = i;
- return(& buf[len]);
- }
- }
- return(NULL);
- } /* get_weekday_name() */
-
- static char *get_month_name(char *, char **, struct tm *);
- static char *get_month_name (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int i;
- int len;
- int num = sizeof(month_names) / sizeof(month_names[0]);
-
- for (i = 0; i < num; i++) {
- len = substrmatch(buf, month_names[i]);
- if (len > 2) {
- tm->tm_mon = i;
- return(& buf[len]);
- }
- }
- return(NULL);
- } /* get_month_name() */
-
-
- static char *match_number(char *, int *, int, int);
- static char *match_number (buf, valp, min, max)
- char *buf;
- int *valp;
- int min;
- int max;
- {
- int num = 0;
- int newnum;
-
- while (isdigit(*buf)) {
- newnum = num * 10 + (*buf - '0');
- if (newnum > max) {
- *valp = num;
- return(buf);
- }
- num = newnum;
- buf++;
- }
- *valp = num;
- return(num >= min ? buf : NULL);
- }
-
- static char *get_month_num(char *, char **, struct tm *);
- static char *get_month_num (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int val = 0;
-
- buf = match_number(buf, &val, 1, 12);
- tm->tm_mon = val - 1;
- CHECK_FOR_SPACES(buf, fmt);
- } /* get_month_num() */
-
- static char *get_year_num(char *, char **, struct tm *);
- static char *get_year_num (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int val = 0;
-
- buf = match_number(buf, &val, 0, 2000);
- tm->tm_year = val % 100;
- CHECK_FOR_SPACES(buf, fmt);
- } /* get_year_num() */
-
- static char *get_hour_num(char *, char **, struct tm *);
- static char *get_hour_num (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int val = 0;
-
- buf = match_number(buf, &val, 0, 23);
- tm->tm_hour = val;
- CHECK_FOR_SPACES(buf, fmt);
- } /* get_hour_num() */
-
- static char *get_minute_num(char *, char **, struct tm *);
- static char *get_minute_num (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int val = 0;
-
- buf = match_number(buf, &val, 0, 59);
- tm->tm_min = val;
- CHECK_FOR_SPACES(buf, fmt);
- } /* get_minute_num() */
-
- static char *get_second_num(char *, char **, struct tm *);
- static char *get_second_num (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int val = 0;
-
- buf = match_number(buf, &val, 0, 59);
- tm->tm_sec = val;
- CHECK_FOR_SPACES(buf, fmt);
- } /* get_second_num() */
-
- static char *get_day_of_year_num(char *, char **, struct tm *);
- static char *get_day_of_year_num (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int val = 0;
-
- buf = match_number(buf, &val, 1, 366);
- tm->tm_yday = val - 1;
- return(buf);
- } /* get_day_of_year_num() */
-
- static char *get_day_of_month_num(char *, char **, struct tm *);
- static char *get_day_of_month_num (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- int val = 0;
-
- buf = match_number(buf, &val, 1, 31);
- tm->tm_mday = val;
- CHECK_FOR_SPACES(buf, fmt);
- } /* get_day_of_month_num() */
-
- static char *get_am_or_pm(char *, char **, struct tm *);
- static char *get_am_or_pm (buf, fmt, tm)
- char *buf;
- char **fmt;
- struct tm *tm;
- {
- if (strncasecmp(buf, "am", 2) == 0) {
- return(& buf[2]);
- }
- else if (strncasecmp(buf, "a.m.", 4) == 0) {
- return(& buf[4]);
- }
- if (strncasecmp(buf, "pm", 2) == 0) {
- buf += 2;
- }
- else if (strncasecmp(buf, "p.m.", 4) == 0) {
- buf += 4;
- }
- else return(NULL);
- if (tm->tm_hour < 12) {
- tm->tm_hour += 12;
- }
- return(buf);
- } /* get_am_or_pm() */
-
- char *string_to_time (buf, fmt, tm)
- char *buf;
- char *fmt;
- struct tm *tm;
- {
- for (; *fmt != '\0'; fmt++) {
- if (*fmt == '%') {
- fmt++;
- switch (*fmt) {
- case 'a' : /* weekday (abbrev or full) */
- case 'A' :
- buf = get_weekday_name(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- break;
-
- case 'b' : /* month (abbrev or full) */
- case 'B' :
- case 'h' :
- buf = get_month_name(buf, &fmt, tm);
- break;
-
- case 'c' : /* same as %x %X */
- break;
-
- case 'C' : /* locale's long-format date and time */
- break;
-
- case 'd' : /* day of month 1-31, leading 0's allowed */
- case 'e' :
- buf = get_day_of_month_num(buf, &fmt, tm);
- break;
-
- case 'D' : /* date as %m/%d/%y */
- buf = get_month_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- if (*buf != '/') {
- if (isspace(*buf)) {
- break;
- }
- return(NULL);
- }
- buf++;
- buf = get_day_of_month_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- if (*buf++ != '/') {
- if (isspace(*buf)) {
- break;
- }
- return(NULL);
- }
- buf = get_year_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- break;
-
- case 'H' : /* hour 0-23, leading 0's allowed */
- case 'k' :
- buf = get_hour_num(buf, &fmt, tm);
- break;
-
- case 'l' : /* hour 0-12, leading 0's allowed */
- case 'L' :
- buf = get_hour_num(buf, &fmt, tm);
- break;
-
- case 'j' : /* day number of year 001-366 */
- buf = get_day_of_year_num(buf, &fmt, tm);
- break;
-
- case 'm' : /* month number 1-12, leading 0's allowed */
- buf = get_month_num(buf, &fmt, tm);
- break;
-
- case 'M' : /* minute, 0-59, leading 0's allowed */
- buf = get_minute_num(buf, &fmt, tm);
- break;
-
- case 'p' : /* AM or PM */
- buf = get_am_or_pm(buf, &fmt, tm);
- break;
-
- case 'r' : /* %l:%M:%S %p */
- buf = get_hour_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- if (*buf++ != ':') {
- if (isspace(*buf)) {
- break;
- }
- return(NULL);
- }
- buf = get_minute_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- if (*buf++ != ':') {
- if (isspace(*buf)) {
- break;
- }
- return(NULL);
- }
- buf = get_second_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- while (isspace(*buf)) {
- buf++;
- }
- buf = get_am_or_pm(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- break;
-
- case 'R' : /* %H:%M */
- buf = get_hour_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- if (*buf++ != ':') {
- if (isspace(*buf)) {
- break;
- }
- return(NULL);
- }
- buf = get_minute_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- break;
-
- case 'S' : /* seconds 0-59, leading 0's allowed */
- buf = get_second_num(buf, &fmt, tm);
- break;
-
- case 'T' : /* time as %H:%M:%S */
- buf = get_hour_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- if (*buf++ != ':') {
- if (isspace(*buf)) {
- break;
- }
- return(NULL);
- }
- buf = get_minute_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- if (*buf++ != ':') {
- if (isspace(*buf)) {
- break;
- }
- return(NULL);
- }
- buf = get_second_num(buf, &fmt, tm);
- if (buf == NULL) {
- return(NULL);
- }
- break;
-
- case 'x' : /* date, using locale's date format */
- break;
-
- case 'X' : /* time, using locale's time format */
- break;
-
- case 'y' : /* year 0-99, leading 0's allowed */
- buf = get_year_num(buf, &fmt, tm);
- break;
-
- case 'Y' : /* year with century ie. 1988 */
- buf = get_year_num(buf, &fmt, tm);
- break;
-
- case '%' : /* matches '%' */
- default :
- if (*buf != *fmt) {
- return(NULL);
- }
- buf++;
- break;
- } /* switch */
- if (buf == NULL) {
- return(NULL);
- }
- } /* *fmt == '%' */
- else if (isspace(*fmt)) {
- /* match any number of spaces, even 0 */
- while (isspace(*buf)) { /* advance buf */
- buf++;
- }
- while (isspace(*fmt)) { /* advance fmt */
- fmt++;
- }
- fmt--;
- }
- else { /* anything else */
- if (*buf != *fmt) {
- return(NULL);
- }
- buf++;
- }
- }
- return(buf);
- } /* string_to_time() */
-
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- char input[101];
- struct tm tm;
- char *ptr;
- if(argc != 2){
- printf("usage: format\n");
- exit(-1);
- }
- while (TRUE) {
- bzero((char *) &tm, sizeof(tm));
- printf("\nEnter date --> ");
- gets(input);
- if (input[0] == 'q') exit(0);
- ptr = string_to_time(input, argv[1], &tm);
- if (ptr == NULL) {
- printf("Returned NULL\n");
- }
- else {
- printf("Read %d chars, '%s'\n",
- ptr - input, ptr);
- }
- printf("\tm_sec\t%d\n", tm.tm_sec);
- printf("\tm_min\t%d\n", tm.tm_min);
- printf("\tm_hour\t%d\n", tm.tm_hour);
- printf("\tm_mday\t%d\n", tm.tm_mday);
- printf("\tm_mon\t%d\n", tm.tm_mon);
- printf("\tm_year\t%d\n", tm.tm_year);
- printf("\tm_wday\t%d\n", tm.tm_wday);
- printf("\tm_yday\t%d\n", tm.tm_yday);
- } /* while () */
- }
-
-
-