date: add date/time setting capability
[Michael Forney: Moved functionality to setdate, other minor tweaks]
This commit is contained in:
parent
1b41610a82
commit
ed78aef5b1
52
date.1
52
date.1
|
@ -3,12 +3,17 @@
|
||||||
.Os sbase
|
.Os sbase
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm date
|
.Nm date
|
||||||
.Nd print date and time
|
.Nd print or set date and time
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl d Ar time
|
.Op Fl d Ar time
|
||||||
.Op Fl u
|
.Op Fl u
|
||||||
.Op Cm + Ns Ar format
|
.Oo
|
||||||
|
.Cm + Ns Ar format |
|
||||||
|
.Sm off
|
||||||
|
.Ar mmddHHMM Oo Oo Ar CC Oc Ar yy Oc
|
||||||
|
.Sm on
|
||||||
|
.Oc
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
prints the date and time according to
|
prints the date and time according to
|
||||||
|
@ -16,7 +21,8 @@ prints the date and time according to
|
||||||
or
|
or
|
||||||
.Ar format
|
.Ar format
|
||||||
using
|
using
|
||||||
.Xr strftime 3 .
|
.Xr strftime 3
|
||||||
|
or sets the date.
|
||||||
.Sh OPTIONS
|
.Sh OPTIONS
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Fl d Ar time
|
.It Fl d Ar time
|
||||||
|
@ -25,8 +31,46 @@ Print
|
||||||
given as the number of seconds since the
|
given as the number of seconds since the
|
||||||
Unix epoch 1970-01-01T00:00:00Z.
|
Unix epoch 1970-01-01T00:00:00Z.
|
||||||
.It Fl u
|
.It Fl u
|
||||||
Print UTC time instead of local time.
|
Print or set UTC time instead of local time.
|
||||||
.El
|
.El
|
||||||
|
.Pp
|
||||||
|
An operand with a leading plus
|
||||||
|
.Pq Cm +
|
||||||
|
sign signals a user-defined format string using
|
||||||
|
.Xr strftime 3
|
||||||
|
conversion specifications.
|
||||||
|
.Pp
|
||||||
|
An operand without a leading plus sign is interpreted as a value
|
||||||
|
for setting the system's current date and time. The canonical
|
||||||
|
representation for setting the date and time is:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width Ds -compact -offset indent
|
||||||
|
.It Ar mm
|
||||||
|
The month of the year, from 01 to 12.
|
||||||
|
.It Ar dd
|
||||||
|
The day of the month, from 01 to 31.
|
||||||
|
.It Ar HH
|
||||||
|
The hour of the day, from 00 to 23.
|
||||||
|
.It Ar MM
|
||||||
|
The minute of the hour, from 00 to 59.
|
||||||
|
.It Ar CC
|
||||||
|
The first two digits of the year (the century).
|
||||||
|
.It Ar yy
|
||||||
|
The second two digits of the year.
|
||||||
|
If
|
||||||
|
.Ar yy
|
||||||
|
is specified, but
|
||||||
|
.Ar CC
|
||||||
|
is not, a value for
|
||||||
|
.Ar yy
|
||||||
|
between 69 and 99 results in a
|
||||||
|
.Ar CC
|
||||||
|
value of 19. Otherwise, a
|
||||||
|
.Ar CC
|
||||||
|
value of 20 is used.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The century and year are optional. The default is the current year.
|
||||||
.Sh STANDARDS
|
.Sh STANDARDS
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
|
69
date.c
69
date.c
|
@ -1,6 +1,8 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -8,7 +10,55 @@
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
eprintf("usage: %s [-u] [-d time] [+format]\n", argv0);
|
eprintf("usage: %s [-u] [-d time] [+format | mmddHHMM[[CC]yy]]\n", argv0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
datefield(const char *s, size_t i)
|
||||||
|
{
|
||||||
|
if (!isdigit(s[i]) || !isdigit(s[i+1]))
|
||||||
|
eprintf("invalid date format: %s\n", s);
|
||||||
|
|
||||||
|
return (s[i] - '0') * 10 + (s[i+1] - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setdate(const char *s, struct tm *now)
|
||||||
|
{
|
||||||
|
struct tm date;
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
switch (strlen(s)) {
|
||||||
|
case 8:
|
||||||
|
date.tm_year = now->tm_year;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
date.tm_year = datefield(s, 8);
|
||||||
|
if (date.tm_year < 69)
|
||||||
|
date.tm_year += 100;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
date.tm_year = ((datefield(s, 8) - 19) * 100) + datefield(s, 10);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf("invalid date format: %s\n", s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
date.tm_mon = datefield(s, 0) - 1;
|
||||||
|
date.tm_mday = datefield(s, 2);
|
||||||
|
date.tm_hour = datefield(s, 4);
|
||||||
|
date.tm_min = datefield(s, 6);
|
||||||
|
date.tm_sec = 0;
|
||||||
|
date.tm_isdst = -1;
|
||||||
|
|
||||||
|
ts.tv_sec = mktime(&date);
|
||||||
|
if (ts.tv_sec == -1)
|
||||||
|
eprintf("mktime:");
|
||||||
|
ts.tv_nsec = 0;
|
||||||
|
|
||||||
|
if (clock_settime(CLOCK_REALTIME, &ts) == -1)
|
||||||
|
eprintf("clock_settime:");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -19,6 +69,8 @@ main(int argc, char *argv[])
|
||||||
char buf[BUFSIZ], *fmt = "%c";
|
char buf[BUFSIZ], *fmt = "%c";
|
||||||
|
|
||||||
t = time(NULL);
|
t = time(NULL);
|
||||||
|
if (t == -1)
|
||||||
|
eprintf("time:");
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
case 'd':
|
case 'd':
|
||||||
|
@ -32,14 +84,17 @@ main(int argc, char *argv[])
|
||||||
usage();
|
usage();
|
||||||
} ARGEND
|
} ARGEND
|
||||||
|
|
||||||
if (argc) {
|
|
||||||
if (argc != 1 || argv[0][0] != '+')
|
|
||||||
usage();
|
|
||||||
else
|
|
||||||
fmt = &argv[0][1];
|
|
||||||
}
|
|
||||||
if (!(now = localtime(&t)))
|
if (!(now = localtime(&t)))
|
||||||
eprintf("localtime:");
|
eprintf("localtime:");
|
||||||
|
if (argc) {
|
||||||
|
if (argc != 1)
|
||||||
|
usage();
|
||||||
|
if (argv[0][0] != '+') {
|
||||||
|
setdate(argv[0], now);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fmt = &argv[0][1];
|
||||||
|
}
|
||||||
|
|
||||||
strftime(buf, sizeof(buf), fmt, now);
|
strftime(buf, sizeof(buf), fmt, now);
|
||||||
puts(buf);
|
puts(buf);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user