commit: efb556f123a37119d65cf0d3d9dadd2c24d41905
parent 8206dfe4fda830164f3af6757edde50c54e4a833
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Mon, 29 Jul 2024 09:41:22 +0200
cmd/date: Add support for `-r epoch` option
In the future it might also support the `-r ref_file` variant
similarly to illumos.
Diffstat:
3 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/cmd/date.1.in b/cmd/date.1.in
@@ -10,7 +10,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl jRu
-.Op Fl d Ar datetime
+.Op Fl d Ar datetime | Fl r Ar epoch
.Op Cm + Ns Ar format
.Nm
.Op Fl jRu
@@ -48,6 +48,11 @@ This allows to use the
flag to convert one datetime to another.
.It Fl u
Use UTC (coordinated universal time) instead of the local time.
+.It Fl r Ar epoch
+Use
+.Ar epoch
+(seconds relative to 1970-01-01 00:00:00 UTC)
+instead of current datetime.
.It Fl R
Set the default value of
.Ar format
@@ -110,6 +115,8 @@ options are present for compatibility with other modern systems such as
NetBSD, BusyBox, and GNU coreutils.
.br
The
+.Fl r
+option is inspired from BSD and illumos,
.Fl f
and
.Fl j
diff --git a/cmd/date.c b/cmd/date.c
@@ -23,7 +23,7 @@ usage()
{
fprintf(stderr, "\
Usage:\n\
- date [-jRu] [-d datetime] [+format]\n\
+ date [-jRu] [-d datetime | -r epoch] [+format]\n\
date [-jRu] mmddHHMM[[CC]yy] [+format]\n\
date [-jRu] -f now_format now [+format]\n\
");
@@ -51,7 +51,7 @@ main(int argc, char *argv[])
char *format = "%c";
char *input_format = NULL;
int uflag = 0;
- int dflag = 0;
+ int dflag = 0, rflag = 0;
int c;
bool jflag = false;
bool settime = false;
@@ -71,7 +71,7 @@ main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- while((c = getopt(argc, argv, ":d:f:jRu")) != -1)
+ while((c = getopt(argc, argv, ":d:f:jr:Ru")) != -1)
{
char *errstr = NULL;
switch(c)
@@ -82,6 +82,11 @@ main(int argc, char *argv[])
fprintf(stderr, "date: Cannot both use '-d' and '-f'\n");
exit(EXIT_FAILURE);
}
+ if(rflag == 1)
+ {
+ fprintf(stderr, "date: Cannot both use '-d' and '-r'\n");
+ exit(EXIT_FAILURE);
+ }
iso_parse(optarg, &tm, &tp.tv_nsec, &errstr);
dflag = 1;
@@ -107,9 +112,43 @@ main(int argc, char *argv[])
fprintf(stderr, "date: Cannot both use '-d' and '-f'\n");
exit(EXIT_FAILURE);
}
+ if(rflag == 1)
+ {
+ fprintf(stderr, "date: Cannot both use '-f' and '-r'\n");
+ exit(EXIT_FAILURE);
+ }
+
input_format = optarg;
settime = true;
break;
+ case 'r': /* seconds relative to epoch */
+ {
+ if(input_format != NULL)
+ {
+ fprintf(stderr, "date: Cannot both use '-f' and '-r'\n");
+ exit(EXIT_FAILURE);
+ }
+ if(dflag == 1)
+ {
+ fprintf(stderr, "date: Cannot both use '-d' and '-r'\n");
+ exit(EXIT_FAILURE);
+ }
+
+ char *endptr = NULL;
+ errno = 0;
+ tp.tv_sec = strtol(optarg, &endptr, 10);
+ if(errno != 0)
+ {
+ fprintf(stderr, "date: Failed parsing '-r %s'\n", optarg);
+ exit(EXIT_FAILURE);
+ }
+ if(!(endptr == NULL || *endptr == '\0'))
+ {
+ fprintf(stderr, "date: Error: Invalid characters in '-r %s': %s\n", optarg, endptr);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ }
case 'R': /* Email (RFC 5322) format */
format = "%a, %d %b %Y %H:%M:%S %z";
break;
diff --git a/test-cmd/date.sh b/test-cmd/date.sh
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: MPL-2.0
target="$(dirname "$0")/../cmd/date"
-plans=19
+plans=22
. "$(dirname "$0")/tap.sh"
unset TZ
@@ -52,6 +52,14 @@ t 'mmddHHMM69' '-j 0628012069 +%Y-%m-%dT%H:%M' '1969-06-28T01:20
t 'mmddHHMMCCyy' '-j 072505542024 +%Y-%m-%dT%H:%M' '2024-07-25T05:54
'
+t 'r_0' '-u -r 0 +%FT%T' '1970-01-01T00:00:00
+'
+t 'r_69' '-u -r 69 +%FT%T' '1970-01-01T00:01:09
+'
+t 'r_-69' '-u -r -69 +%FT%T' '1969-12-31T23:58:51
+'
+
+
#usage="\
#date [-uR] [-d datetime] [+format]
#date [-uR] -f now_format now [+format]