diff --git a/bin/date/Makefile b/bin/date/Makefile index ed2bf8fad3ea..d6562b4b5094 100644 --- a/bin/date/Makefile +++ b/bin/date/Makefile @@ -1,8 +1,9 @@ # @(#)Makefile 8.1 (Berkeley) 5/31/93 -# $Id: Makefile,v 1.4 1997/02/22 14:02:30 peter Exp $ +# $Id: Makefile,v 1.5 1997/08/04 03:37:05 brian Exp $ PROG= date SRCS= date.c netdate.c vary.c +CFLAGS+=-Wall DPADD= ${LIBUTIL} LDADD= -lutil diff --git a/bin/date/date.1 b/bin/date/date.1 index 7e8bf481ac00..f14009a748ef 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.12 1997/04/16 05:59:20 danny Exp $ +.\" $Id: date.1,v 1.13 1997/08/04 03:37:05 brian Exp $ .\" .Dd November 17, 1993 .Dt DATE 1 @@ -48,8 +48,9 @@ .Op Fl t Ar minutes_west .Op Fl nu .Op Cm + Ns Ar format -.Op Fl DWMY Ar [+|-]val -.Op [[[[yy]mm]dd]hh]mm[\&.ss] +.Op Fl v Ar [+|-]val[ymwdHM] +.Ar ... +.Op [[[[yy]mm]dd]HH]MM[\&.ss] .Sh DESCRIPTION .Nm displays the current date and time when invoked without arguments. @@ -98,8 +99,8 @@ by future calls to Display or set the date in .Tn UCT (universal) time. -.It Fl DWMY -Adjust the month day, week day, month or year according to +.It Fl v +Adjust the minute, hour, month day, week day, month or year according to .Ar val . If .Ar val @@ -108,9 +109,22 @@ or backwards according to the remaining string, otherwise the relevent part of the date is set. The date can be adjusted as many times as required using these flags. Flags are processed in the order given. .Pp -Month days are in the range 1-31, week days are in the range 0-6 -(sun-sat), months are in the range 1-12 (jan-dec) and years are in -the range 80-38 or 1980-2038. +Minutes are in the range 0-59, hours are in the range 1-12, month days +are in the range 1-31, week days are in the range 0-6 (sun-sat), months +are in the range 1-12 (jan-dec) and years are in the range 80-38 or +1980-2038. +.Pp +If +.Ar val +is numeric, one of either +.Ar y , +.Ar m , +.Ar w , +.Ar d , +.Ar H +or +.Ar M +must be used to specify which part of the date is to be adjusted. .Pp The week day or month may be specified using a name rather than a number. If a name is used with the plus (or minus) sign, the date @@ -172,7 +186,7 @@ TIME: 13:36:16 .Pp The command: .Bd -literal -offset indent -date -M1 -Y+1 +date -v1m -v+1y .Ed .Pp will display: @@ -184,7 +198,7 @@ Sun Jan 4 03:15:24 GMT 1998 .Pp The command: .Bd -literal -offset indent -date -D1 -M3 -Y0 -D-1 +date -v1d -v3m -v0y -v-1d .Ed .Pp will display the last day of February in the year 2000: @@ -194,7 +208,7 @@ Tue Feb 29 03:18:00 GMT 2000 .Pp The command: .Bd -literal -offset indent -date -D1 -M+1 -D-1 -W-fri +date -v1d -v+1m -v-1d -v-fri .Ed .Pp will display the last friday of the month: diff --git a/bin/date/date.c b/bin/date/date.c index ad9ffcab8e54..c6e6d5170d82 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.13 1997/06/06 06:34:37 charnier Exp $ + * $Id: date.c,v 1.14 1997/08/04 03:37:06 brian Exp $ */ #ifndef lint @@ -89,7 +89,7 @@ main(argc, argv) tz.tz_dsttime = tz.tz_minuteswest = 0; rflag = 0; set_timezone = 0; - while ((ch = getopt(argc, argv, "D:W:M:Y:d:nr:ut:")) != -1) + while ((ch = getopt(argc, argv, "d:nr:ut:v:")) != -1) switch((char)ch) { case 'd': /* daylight savings time */ tz.tz_dsttime = strtol(optarg, &endptr, 10) ? 1 : 0; @@ -114,11 +114,8 @@ main(argc, argv) usage(); set_timezone = 1; break; - case 'D': - case 'W': - case 'M': - case 'Y': - v = vary_append(v, ch, optarg); + case 'v': + v = vary_append(v, optarg); break; default: usage(); @@ -155,8 +152,8 @@ main(argc, argv) lt = *localtime(&tval); badv = vary_apply(v, <); if (badv) { - fprintf(stderr, "-%c %s: Cannot apply date adjustment\n", - badv->flag, badv->arg); + fprintf(stderr, "%s: Cannot apply date adjustment\n", + badv->arg); vary_destroy(v); usage(); } @@ -258,7 +255,7 @@ static void usage() { (void)fprintf(stderr, "%s\n%s\n", - "usage: date [-nu] [-d dst] [-r seconds] [-t west] [+format]", - " [-DWMY [+|-]val] [[[[yy]mm]dd]HH]MM[.ss]]"); + "usage: date [-nu] [-d dst] [-r seconds] [-t west] [+format]", + " [-v [+|-]val[ymwdHM]]... [[[[yy]mm]dd]HH]MM[.ss]]"); exit(1); } diff --git a/bin/date/vary.c b/bin/date/vary.c index 5df3a0cb6caa..be9f76240e38 100644 --- a/bin/date/vary.c +++ b/bin/date/vary.c @@ -9,9 +9,6 @@ struct trans { }; static struct trans trans_mon[] = { - { 1, "jan" }, { 2, "feb" }, { 3, "mar" }, { 4, "apr" }, { 5, "may" }, - { 6, "jun" }, { 7, "jul" }, { 8, "aug" }, { 9, "sep" }, { 10, "oct" }, - { 11, "nov" }, { 12, "dec" }, { 1, "january" }, { 2, "february" }, { 3, "march" }, { 4, "april" }, { 6, "june" }, { 7, "july" }, { 8, "august" }, { 9, "september" }, { 10, "october" }, { 11, "november" }, { 12, "december" }, @@ -19,8 +16,6 @@ static struct trans trans_mon[] = { }; static struct trans trans_wday[] = { - { 0, "sun" }, { 1, "mon" }, { 2, "tue" }, { 3, "wed" }, { 4, "thr" }, - { 4, "thu" }, { 5, "fri" }, { 6, "sat" }, { 0, "sunday" }, { 1, "monday" }, { 2, "tuesday" }, { 3, "wednesday" }, { 4, "thursday" }, { 5, "friday" }, { 6, "saturday" }, { -1, NULL } @@ -33,24 +28,19 @@ trans(const struct trans t[], const char *arg) { int f; - if (strspn(arg, digits) == strlen(arg)) - return atoi(arg); - for (f = 0; t[f].val != -1; f++) - if (!strcasecmp(t[f].str, arg)) + if (!strncasecmp(t[f].str, arg, 3) || + !strncasecmp(t[f].str, arg, strlen(t[f].str))) return t[f].val; return -1; } struct vary * -vary_append(struct vary *v, char flag, char *arg) +vary_append(struct vary *v, char *arg) { struct vary *result, **nextp; - if (!strchr("DWMY", flag)) - return 0; - if (v) { result = v; while (v->next) @@ -60,7 +50,6 @@ vary_append(struct vary *v, char flag, char *arg) nextp = &result; *nextp = (struct vary *)malloc(sizeof(struct vary)); - (*nextp)->flag = flag; (*nextp)->arg = arg; (*nextp)->next = NULL; return result; @@ -112,18 +101,6 @@ adjyear(struct tm *t, char type, int val) return mktime(t) != -1; } -static int -sadjyear(struct tm *t, char *arg) -{ - switch (*arg) { - case '+': - case '-': - return adjyear(t, *arg, atoi(arg+1)); - default: - return adjyear(t, '\0', atoi(arg)); - } -} - static int adjmon(struct tm *t, char type, int val, int istext) { @@ -171,25 +148,6 @@ adjmon(struct tm *t, char type, int val, int istext) return mktime(t) != -1; } -static int -sadjmon(struct tm *t, char *arg) -{ - int istext; - int val; - - switch (*arg) { - case '+': - case '-': - istext = strspn(arg+1, digits) != strlen(arg+1); - val = trans(trans_mon, arg+1); - return adjmon(t, *arg, val, istext); - default: - istext = strspn(arg, digits) != strlen(arg); - val = trans(trans_mon, arg); - return adjmon(t, '\0', val, istext); - } -} - static int adjday(struct tm *t, char type, int val) { @@ -234,27 +192,12 @@ adjday(struct tm *t, char type, int val) } static int -sadjwday(struct tm *t, char *arg) +adjwday(struct tm *t, char type, int val, int istext) { - int istext; - int val; - - switch (*arg) { - case '+': - case '-': - istext = strspn(arg+1, digits) != strlen(arg+1); - val = trans(trans_wday, arg+1); - break; - default: - istext = 0; - val = trans(trans_wday, arg); - break; - } - if (val < 0) return 0; - switch (*arg) { + switch (type) { case '+': if (istext) if (val < t->tm_wday) @@ -285,40 +228,144 @@ sadjwday(struct tm *t, char *arg) } static int -sadjday(struct tm *t, char *arg) +adjhour(struct tm *t, char type, int val) { - switch (*arg) { + if (val < 0) + return 0; + + switch (type) { case '+': + if (!adjday(t, '+', (t->tm_hour + val) / 24)) + return 0; + val %= 24; + t->tm_hour += val; + if (t->tm_hour > 23) + t->tm_hour -= 24; + break; + case '-': - return adjday(t, *arg, atoi(arg+1)); + if (!adjday(t, '-', val / 24)) + return 0; + val %= 24; + if (val > t->tm_hour) { + if (!adjday(t, '-', 1)) + return 0; + val -= 24; + } + t->tm_hour -= val; + break; + default: - return adjday(t, '\0', atoi(arg)); + if (val > 23) + return 0; + t->tm_hour = val; } + + return mktime(t) != -1; +} + +static int +adjmin(struct tm *t, char type, int val) +{ + if (val < 0) + return 0; + + switch (type) { + case '+': + if (!adjhour(t, '+', (t->tm_min + val) / 60)) + return 0; + val %= 60; + t->tm_min += val; + if (t->tm_min > 59) + t->tm_min -= 60; + break; + + case '-': + if (!adjhour(t, '-', val / 60)) + return 0; + val %= 60; + if (val > t->tm_min) { + if (!adjhour(t, '-', 1)) + return 0; + val -= 60; + } + t->tm_min -= val; + break; + + default: + if (val > 59) + return 0; + t->tm_min = val; + } + + return mktime(t) != -1; } const struct vary * vary_apply(const struct vary *v, struct tm *t) { + char type; + char which; + char *arg; + int len; + int val; + for (; v; v = v->next) { - switch (v->flag) { - case 'D': - if (!sadjday(t, v->arg)) + type = *v->arg; + arg = v->arg; + if (type == '+' || type == '-') + arg++; + else + type = '\0'; + len = strlen(arg); + if (len < 2) + return v; + + if (strspn(arg, digits) != len-1) { + val = trans(trans_wday, arg); + if (val != -1) { + if (!adjwday(t, type, val, 1)) + return v; + } else { + val = trans(trans_mon, arg); + if (val != -1) { + if (!adjmon(t, type, val, 1)) + return v; + } else return v; - break; - case 'W': - if (!sadjwday(t, v->arg)) + } + } else { + val = atoi(arg); + which = arg[len-1]; + + switch (which) { + case 'M': + if (!adjmin(t, type, val)) + return v; + break; + case 'H': + if (!adjhour(t, type, val)) + return v; + break; + case 'd': + if (!adjday(t, type, val)) + return v; + break; + case 'w': + if (!adjwday(t, type, val, 0)) + return v; + break; + case 'm': + if (!adjmon(t, type, val, 0)) + return v; + break; + case 'y': + if (!adjyear(t, type, val)) + return v; + break; + default: return v; - break; - case 'M': - if (!sadjmon(t, v->arg)) - return v; - break; - case 'Y': - if (!sadjyear(t, v->arg)) - return v; - break; - default: - return v; + } } } return 0; diff --git a/bin/date/vary.h b/bin/date/vary.h index 146706f1d768..6f54b88c4d96 100644 --- a/bin/date/vary.h +++ b/bin/date/vary.h @@ -1,9 +1,8 @@ struct vary { - char flag; char *arg; struct vary *next; }; -extern struct vary *vary_append(struct vary *v, char flag, char *arg); +extern struct vary *vary_append(struct vary *v, char *arg); extern const struct vary *vary_apply(const struct vary *v, struct tm *t); extern void vary_destroy(struct vary *v);