aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2023-05-19 09:08:11 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2023-05-19 19:09:40 +0000
commit31edf56b157169b2f83d288ebfae7d4b15ce6dde (patch)
treeb246052295de156aecd57c0d104efd828fc408d9
parentec6d620b197e0973102db134a59e34efcc4bbec8 (diff)
downloadsrc-31edf56b1571.tar.gz
src-31edf56b1571.zip
date: add -z output_zone option
Inpired by OpenBSD date(1), this option allows to do timezone conversion via the date(1) command. For example, to determine when the BSDCan livestream begins for me: $ env -i TZ=EST5EDT date -z Europe/Paris -j 0900 MFC After: 1 week Reviewed by: kib, bcr (manpage) Differential Revision: https://reviews.freebsd.org/D40159
-rw-r--r--bin/date/date.122
-rw-r--r--bin/date/date.c12
2 files changed, 29 insertions, 5 deletions
diff --git a/bin/date/date.1 b/bin/date/date.1
index 0c92a8c71f90..b8a1ae9718c1 100644
--- a/bin/date/date.1
+++ b/bin/date/date.1
@@ -32,7 +32,7 @@
.\" @(#)date.1 8.3 (Berkeley) 4/28/95
.\" $FreeBSD$
.\"
-.Dd April 13, 2023
+.Dd May 19, 2023
.Dt DATE 1
.Os
.Sh NAME
@@ -42,6 +42,7 @@
.\" Display time.
.Nm
.Op Fl nRu
+.Op Fl z Ar output_zone
.Op Fl I Ns Op Ar FMT
.Op Fl r Ar filename
.Op Fl r Ar seconds
@@ -56,6 +57,7 @@
.\" Set time with the default input format.
.Nm
.Op Fl jnRu
+.Op Fl z Ar output_zone
.Op Fl I Ns Op Ar FMT
.Oo
.Sm off
@@ -77,6 +79,7 @@
.\" Set time with the user-provided input format.
.Nm
.Op Fl jnRu
+.Op Fl z Ar output_zone
.Op Fl I Ns Op Ar FMT
.Oo
.Sm off
@@ -202,6 +205,14 @@ displays the time in the time zone described by
or the
.Ev TZ
environment variable.
+.It Fl z Ar output_zone
+Just before printing the time, change to the specified timezone;
+see the description of
+.Ev TZ
+below.
+This can be used with
+.Fl j
+to easily convert time specifications from one zone to another.
.It Xo
.Fl v
.Sm off
@@ -514,13 +525,20 @@ will display
.Pp
.Dl "2018-08-04T13:42:19-07:00"
.Pp
-Finally the command:
+The command:
.Pp
.Dl "env LC_ALL=C date -j -f ""%a %b %d %T %Z %Y"" ""`env LC_ALL=C date`"" ""+%s"""
.Pp
can be used to parse the output from
.Nm
and express it in Epoch time.
+.Pp
+Finally the command
+.Pp
+.Dl "TZ=America/Los_Angeles date -z Europe/Paris -j 0900"
+.Pp
+will print the time in the "Europe/Paris" timezone when it is 9:00 in The
+America/Los_Angeles timezone.
.Sh DIAGNOSTICS
It is invalid to combine the
.Fl I
diff --git a/bin/date/date.c b/bin/date/date.c
index 4dc5df0dccfc..c1fb496ce7ee 100644
--- a/bin/date/date.c
+++ b/bin/date/date.c
@@ -95,7 +95,7 @@ main(int argc, char *argv[])
bool Iflag, jflag, Rflag;
const char *format;
char buf[1024];
- char *fmt;
+ char *fmt, *outzone = NULL;
char *tmp;
struct vary *v;
const struct vary *badv;
@@ -108,7 +108,7 @@ main(int argc, char *argv[])
(void) setlocale(LC_TIME, "");
rflag = 0;
Iflag = jflag = Rflag = 0;
- while ((ch = getopt(argc, argv, "f:I::jnRr:uv:")) != -1)
+ while ((ch = getopt(argc, argv, "f:I::jnRr:uv:z:")) != -1)
switch((char)ch) {
case 'f':
fmt = optarg;
@@ -152,6 +152,9 @@ main(int argc, char *argv[])
case 'u': /* do everything in UTC */
(void)setenv("TZ", "UTC0", 1);
break;
+ case 'z':
+ outzone = optarg;
+ break;
case 'v':
v = vary_append(v, optarg);
break;
@@ -189,6 +192,8 @@ main(int argc, char *argv[])
format = *argv + 1;
}
+ if (outzone != NULL && setenv("TZ", outzone, 1) != 0)
+ err(1, "setenv(TZ)");
lt = localtime(&tval);
if (lt == NULL)
errx(1, "invalid time");
@@ -211,6 +216,7 @@ main(int argc, char *argv[])
*/
setlocale(LC_TIME, "C");
+
(void)strftime(buf, sizeof(buf), format, lt);
printdate(buf);
}
@@ -385,7 +391,7 @@ usage(void)
(void)fprintf(stderr, "%s\n%s\n%s\n",
"usage: date [-jnRu] [-I[date|hours|minutes|seconds]] [-f input_fmt]",
" "
- "[-r filename|seconds] [-v[+|-]val[y|m|w|d|H|M|S]]",
+ "[ -z output_zone ] [-r filename|seconds] [-v[+|-]val[y|m|w|d|H|M|S]]",
" "
"[[[[[[cc]yy]mm]dd]HH]MM[.SS] | new_date] [+output_fmt]"
);