From e2cda524da9ffbfdadc52c8c4d4f27be676498be Mon Sep 17 00:00:00 2001 From: brian Date: Sun, 10 Aug 1997 16:36:59 +0000 Subject: Add "-f fmt date" for specification of the date using strptime(3). Suggested by: Michael Smith Change mm & dd to MM & DD so that they don't clash with the month. --- bin/date/date.1 | 17 +++++-- bin/date/date.c | 139 ++++++++++++++++++++++++++++++++------------------------ 2 files changed, 93 insertions(+), 63 deletions(-) (limited to 'bin') diff --git a/bin/date/date.1 b/bin/date/date.1 index f14009a..6a68518 100644 --- a/bin/date/date.1 +++ b/bin/date/date.1 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)date.1 8.3 (Berkeley) 4/28/95 -.\" $Id: date.1,v 1.13 1997/08/04 03:37:05 brian Exp $ +.\" $Id: date.1,v 1.14 1997/08/09 22:34:03 brian Exp $ .\" .Dd November 17, 1993 .Dt DATE 1 @@ -50,7 +50,7 @@ .Op Cm + Ns Ar format .Op Fl v Ar [+|-]val[ymwdHM] .Ar ... -.Op [[[[yy]mm]dd]HH]MM[\&.ss] +.Op Fl f Ar fmt Ar date | [[[[yy]mm]dd]HH]MM[\&.ss] .Sh DESCRIPTION .Nm displays the current date and time when invoked without arguments. @@ -69,6 +69,14 @@ to .Xr gettimeofday 2 will return a non-zero .Ql tz_dsttime . +.It Fl f +Use +.Ar fmt +as the format string to parse the date provided rather than using +the default +.Ar [[[[yy]mm]dd]HH]MM[.ss] +format. Parsing is done using +.Xr strptime 3 . .It Fl n The utility .Xr timed 8 @@ -160,9 +168,9 @@ Numeric month. A number from 1 to 12. .It Ar dd Day, a number from 1 to 31. -.It Ar hh +.It Ar HH Hour, a number from 0 to 23. -.It Ar mm +.It Ar MM Minutes, a number from 0 to 59. .It Ar .ss Seconds, a number from 0 to 61 (59 plus a maximum of two leap seconds). @@ -255,6 +263,7 @@ A record of the user setting the time. .Sh SEE ALSO .Xr gettimeofday 2 , .Xr strftime 3 , +.Xr strptime 3 , .Xr utmp 5 , .Xr timed 8 .Rs diff --git a/bin/date/date.c b/bin/date/date.c index c6e6d517..006a0c7 100644 --- a/bin/date/date.c +++ b/bin/date/date.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: date.c,v 1.14 1997/08/04 03:37:06 brian Exp $ + * $Id: date.c,v 1.15 1997/08/09 22:34:04 brian Exp $ */ #ifndef lint @@ -62,7 +62,7 @@ static char const sccsid[] = "@(#)date.c 8.2 (Berkeley) 4/28/95"; time_t tval; int retval, nflag; -static void setthetime __P((char *)); +static void setthetime __P((const char *, const char *)); static void badformat __P((void)); static void usage __P((void)); @@ -78,18 +78,19 @@ main(argc, argv) struct timezone tz; int ch, rflag; char *format, buf[1024]; - char *endptr; + char *endptr, *fmt; int set_timezone; struct vary *v; const struct vary *badv; struct tm lt; v = NULL; + fmt = NULL; (void) setlocale(LC_TIME, ""); tz.tz_dsttime = tz.tz_minuteswest = 0; rflag = 0; set_timezone = 0; - while ((ch = getopt(argc, argv, "d:nr:ut:v:")) != -1) + while ((ch = getopt(argc, argv, "d:f:nr:t:uv:")) != -1) switch((char)ch) { case 'd': /* daylight savings time */ tz.tz_dsttime = strtol(optarg, &endptr, 10) ? 1 : 0; @@ -97,6 +98,9 @@ main(argc, argv) usage(); set_timezone = 1; break; + case 'f': + fmt = optarg; + break; case 'n': /* don't set network */ nflag = 1; break; @@ -104,9 +108,6 @@ main(argc, argv) rflag = 1; tval = atol(optarg); break; - case 'u': /* do everything in GMT */ - (void)setenv("TZ", "GMT0", 1); - break; case 't': /* minutes west of GMT */ /* error check; don't allow "PST" */ tz.tz_minuteswest = strtol(optarg, &endptr, 10); @@ -114,6 +115,9 @@ main(argc, argv) usage(); set_timezone = 1; break; + case 'u': /* do everything in GMT */ + (void)setenv("TZ", "GMT0", 1); + break; case 'v': v = vary_append(v, optarg); break; @@ -142,9 +146,10 @@ main(argc, argv) } if (*argv) { - setthetime(*argv); + setthetime(fmt, *argv); ++argv; - } + } else if (fmt != NULL) + usage(); if (*argv && **argv == '+') format = *argv + 1; @@ -165,64 +170,79 @@ main(argc, argv) #define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; void -setthetime(p) - register char *p; +setthetime(fmt, p) + const char *fmt; + register const char *p; { register struct tm *lt; struct timeval tv; - char *dot, *t; + const char *dot, *t; - for (t = p, dot = NULL; *t; ++t) { - if (isdigit(*t)) - continue; - if (*t == '.' && dot == NULL) { - dot = t; - continue; + if (fmt != NULL) { + lt = localtime(&tval); + t = strptime(p, fmt, lt); + if (t == NULL) { + fprintf(stderr, "Failed conversion of ``%s''" + " using format ``%s''\n", p, fmt); + lt = localtime(&tval); + return; + } else if (*t != '\0') + fprintf(stderr, "Warning: Ignoring %d extraneous" + " characters in date string (%s)\n", + strlen(t), t); + } else { + for (t = p, dot = NULL; *t; ++t) { + if (isdigit(*t)) + continue; + if (*t == '.' && dot == NULL) { + dot = t; + continue; + } + badformat(); } - badformat(); - } - lt = localtime(&tval); + lt = localtime(&tval); - if (dot != NULL) { /* .ss */ - *dot++ = '\0'; - if (strlen(dot) != 2) - badformat(); - lt->tm_sec = ATOI2(dot); - if (lt->tm_sec > 61) - badformat(); - } else - lt->tm_sec = 0; + if (dot != NULL) { /* .ss */ + dot++; /* *dot++ = '\0'; */ + if (strlen(dot) != 2) + badformat(); + lt->tm_sec = ATOI2(dot); + if (lt->tm_sec > 61) + badformat(); + } else + lt->tm_sec = 0; - switch (strlen(p)) { - case 10: /* yy */ - lt->tm_year = ATOI2(p); - if (lt->tm_year < 69) /* hack for 2000 ;-} */ - lt->tm_year += 100; - /* FALLTHROUGH */ - case 8: /* mm */ - lt->tm_mon = ATOI2(p); - if (lt->tm_mon > 12) - badformat(); - --lt->tm_mon; /* time struct is 0 - 11 */ - /* FALLTHROUGH */ - case 6: /* dd */ - lt->tm_mday = ATOI2(p); - if (lt->tm_mday > 31) - badformat(); - /* FALLTHROUGH */ - case 4: /* hh */ - lt->tm_hour = ATOI2(p); - if (lt->tm_hour > 23) - badformat(); - /* FALLTHROUGH */ - case 2: /* mm */ - lt->tm_min = ATOI2(p); - if (lt->tm_min > 59) + switch (strlen(p)) { + case 10: /* yy */ + lt->tm_year = ATOI2(p); + if (lt->tm_year < 69) /* hack for 2000 ;-} */ + lt->tm_year += 100; + /* FALLTHROUGH */ + case 8: /* mm */ + lt->tm_mon = ATOI2(p); + if (lt->tm_mon > 12) + badformat(); + --lt->tm_mon; /* time struct is 0 - 11 */ + /* FALLTHROUGH */ + case 6: /* dd */ + lt->tm_mday = ATOI2(p); + if (lt->tm_mday > 31) + badformat(); + /* FALLTHROUGH */ + case 4: /* HH */ + lt->tm_hour = ATOI2(p); + if (lt->tm_hour > 23) + badformat(); + /* FALLTHROUGH */ + case 2: /* MM */ + lt->tm_min = ATOI2(p); + if (lt->tm_min > 59) + badformat(); + break; + default: badformat(); - break; - default: - badformat(); + } } /* convert broken-down time to GMT clock time */ @@ -234,6 +254,7 @@ setthetime(p) logwtmp("|", "date", ""); tv.tv_sec = tval; tv.tv_usec = 0; +fprintf(stderr, "Set to \"%s\"\n", asctime(lt)); if (settimeofday(&tv, (struct timezone *)NULL)) err(1, "settimeofday (timeval)"); logwtmp("{", "date", ""); @@ -256,6 +277,6 @@ usage() { (void)fprintf(stderr, "%s\n%s\n", "usage: date [-nu] [-d dst] [-r seconds] [-t west] [+format]", - " [-v [+|-]val[ymwdHM]]... [[[[yy]mm]dd]HH]MM[.ss]]"); + " [-v [+|-]val[ymwdHM]] ... [-f fmt date | [[[[yy]mm]dd]HH]MM[.ss]]"); exit(1); } -- cgit v1.1