diff options
author | P. J. McDermott <pj@pehjota.net> | 2021-08-28 17:53:27 (EDT) |
---|---|---|
committer | P. J. McDermott <pj@pehjota.net> | 2021-08-29 12:45:36 (EDT) |
commit | 4bf5cad1d4f42dc8b7321e84fba8acf4ece5d6a1 (patch) | |
tree | c81b72e7ab042058018f51c03110bf6fed71be44 | |
parent | 28226fed7a52114efbd43860ef1ff7794ce88931 (diff) | |
download | atsign-4bf5cad1d4f42dc8b7321e84fba8acf4ece5d6a1.zip atsign-4bf5cad1d4f42dc8b7321e84fba8acf4ece5d6a1.tar.gz atsign-4bf5cad1d4f42dc8b7321e84fba8acf4ece5d6a1.tar.bz2 |
datetime: Further implement
Simplify concatenation, factor out formats, and determine date if not
specified.
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/datetime-formats.c | 434 | ||||
-rw-r--r-- | src/datetime.c | 115 | ||||
-rw-r--r-- | src/datetime.h | 22 | ||||
-rw-r--r-- | src/local.mk | 3 | ||||
-rw-r--r-- | src/main.c | 29 |
6 files changed, 555 insertions, 50 deletions
diff --git a/configure.ac b/configure.ac index 7e72e6d..4a874b7 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,8 @@ test -d "${srcdir}/.git" || CFLAGS="${save_CFLAGS}" funcs_missing=false AC_CHECK_FUNCS( [\ + calloc fprintf free localtime mktime printf strerror strlen \ + strptime time ], [], [funcs_missing=true]) diff --git a/src/datetime-formats.c b/src/datetime-formats.c new file mode 100644 index 0000000..3c0d099 --- /dev/null +++ b/src/datetime-formats.c @@ -0,0 +1,434 @@ +/* + * Copyright (C) 2021 P. J. McDermott + * + * This file is part of @ + * + * @ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with @. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Time only */ +" %I:%M:%S %p ", +" %H:%M:%S ", +" %I:%M %p ", +" %H:%M ", +" %I%M%S %p ", +" %H%M%S ", +" %I%M %p ", +" %H%M ", + +/* ISO 8601: 1969-12-31 delimited by "T" */ +" %Y-%m-%dT%H:%M:%S ", +" %Y-%m-%dT%H:%M ", + +/* ISO 8601: 19691231 delimited by "T" */ +" %Y%m%dT%H%M%S ", +" %Y%m%dT%H%M ", + +/* 1969-12-31 */ +" %Y-%m-%d %I:%M:%S %p ", +" %Y-%m-%d %H:%M:%S ", +" %Y-%m-%d %I:%M %p ", +" %Y-%m-%d %H:%M ", +" %Y-%m-%d %I%M%S %p ", +" %Y-%m-%d %H%M%S ", +" %Y-%m-%d %I%M %p ", +" %Y-%m-%d %H%M ", +" %I:%M:%S %p %Y-%m-%d ", +" %H:%M:%S %Y-%m-%d ", +" %I:%M %p %Y-%m-%d ", +" %H:%M %Y-%m-%d ", +" %I%M%S %p %Y-%m-%d ", +" %H%M%S %Y-%m-%d ", +" %I%M %p %Y-%m-%d ", +" %H%M %Y-%m-%d ", + +/* 19691231 */ +" %Y%m%d %I%M%S %p ", +" %Y%m%d %H%M%S ", +" %Y%m%d %I%M %p ", +" %Y%m%d %H%M ", +" %I%M%S %p %Y%m%d ", +" %H%M%S %Y%m%d ", +" %I%M %p %Y%m%d ", +" %H%M %Y%m%d ", + +/* 1969/12/31 */ +" %Y/%m/%d %I:%M:%S %p ", +" %Y/%m/%d %H:%M:%S ", +" %Y/%m/%d %I:%M %p ", +" %Y/%m/%d %H:%M ", +" %Y/%m/%d %I%M%S %p ", +" %Y/%m/%d %H%M%S ", +" %Y/%m/%d %I%M %p ", +" %Y/%m/%d %H%M ", +" %I:%M:%S %p %Y/%m/%d ", +" %H:%M:%S %Y/%m/%d ", +" %I:%M %p %Y/%m/%d ", +" %H:%M %Y/%m/%d ", +" %I%M%S %p %Y/%m/%d ", +" %H%M%S %Y/%m/%d ", +" %I%M %p %Y/%m/%d ", +" %H%M %Y/%m/%d ", + +/* 12-31-1969 */ +" %m-%d-%Y %I:%M:%S %p ", +" %m-%d-%Y %H:%M:%S ", +" %m-%d-%Y %I:%M %p ", +" %m-%d-%Y %H:%M ", +" %m-%d-%Y %I%M%S %p ", +" %m-%d-%Y %H%M%S ", +" %m-%d-%Y %I%M %p ", +" %m-%d-%Y %H%M ", +" %I:%M:%S %p %m-%d-%Y ", +" %H:%M:%S %m-%d-%Y ", +" %I:%M %p %m-%d-%Y ", +" %H:%M %m-%d-%Y ", +" %I%M%S %p %m-%d-%Y ", +" %H%M%S %m-%d-%Y ", +" %I%M %p %m-%d-%Y ", +" %H%M %m-%d-%Y ", + +/* 12/31/1969 */ +" %m/%d/%Y %I:%M:%S %p ", +" %m/%d/%Y %H:%M:%S ", +" %m/%d/%Y %I:%M %p ", +" %m/%d/%Y %H:%M ", +" %m/%d/%Y %I%M%S %p ", +" %m/%d/%Y %H%M%S ", +" %m/%d/%Y %I%M %p ", +" %m/%d/%Y %H%M ", + +/* 31 Dec 1969 */ +" %d %b %Y %I:%M:%S %p ", +" %d %b %Y %H:%M:%S ", +" %d %b %Y %I:%M %p ", +" %d %b %Y %H:%M ", +" %d %b %Y %I%M%S %p ", +" %d %b %Y %H%M%S ", +" %d %b %Y %I%M %p ", +" %d %b %Y %H%M ", +" %I:%M:%S %p %d %b %Y ", +" %H:%M:%S %d %b %Y ", +" %I:%M %p %d %b %Y ", +" %H:%M %d %b %Y ", +" %I%M%S %p %d %b %Y ", +" %H%M%S %d %b %Y ", +" %I%M %p %d %b %Y ", +" %H%M %d %b %Y ", + +/* 31-Dec-1969 */ +" %d-%b-%Y %I:%M:%S %p ", +" %d-%b-%Y %H:%M:%S ", +" %d-%b-%Y %I:%M %p ", +" %d-%b-%Y %H:%M ", +" %d-%b-%Y %I%M%S %p ", +" %d-%b-%Y %H%M%S ", +" %d-%b-%Y %I%M %p ", +" %d-%b-%Y %H%M ", +" %I:%M:%S %p %d-%b-%Y ", +" %H:%M:%S %d-%b-%Y ", +" %I:%M %p %d-%b-%Y ", +" %H:%M %d-%b-%Y ", +" %I%M%S %p %d-%b-%Y ", +" %H%M%S %d-%b-%Y ", +" %I%M %p %d-%b-%Y ", +" %H%M %d-%b-%Y ", + +/* 31/Dec/1969 */ +" %d/%b/%Y %I:%M:%S %p ", +" %d/%b/%Y %H:%M:%S ", +" %d/%b/%Y %I:%M %p ", +" %d/%b/%Y %H:%M ", +" %d/%b/%Y %I%M%S %p ", +" %d/%b/%Y %H%M%S ", +" %d/%b/%Y %I%M %p ", +" %d/%b/%Y %H%M ", +" %I:%M:%S %p %d/%b/%Y ", +" %H:%M:%S %d/%b/%Y ", +" %I:%M %p %d/%b/%Y ", +" %H:%M %d/%b/%Y ", +" %I%M%S %p %d/%b/%Y ", +" %H%M%S %d/%b/%Y ", +" %I%M %p %d/%b/%Y ", +" %H%M %d/%b/%Y ", + +/* Wed 31 Dec 1969 */ +" %a %d %b %Y %I:%M:%S %p ", +" %a %d %b %Y %H:%M:%S ", +" %a %d %b %Y %I:%M %p ", +" %a %d %b %Y %H:%M ", +" %a %d %b %Y %I%M%S %p ", +" %a %d %b %Y %H%M%S ", +" %a %d %b %Y %I%M %p ", +" %a %d %b %Y %H%M ", +" %I:%M:%S %p %a %d %b %Y ", +" %H:%M:%S %a %d %b %Y ", +" %I:%M %p %a %d %b %Y ", +" %H:%M %a %d %b %Y ", +" %I%M%S %p %a %d %b %Y ", +" %H%M%S %a %d %b %Y ", +" %I%M %p %a %d %b %Y ", +" %H%M %a %d %b %Y ", + +/* Wed 31-Dec-1969 */ +" %a %d-%b-%Y %I:%M:%S %p ", +" %a %d-%b-%Y %H:%M:%S ", +" %a %d-%b-%Y %I:%M %p ", +" %a %d-%b-%Y %H:%M ", +" %a %d-%b-%Y %I%M%S %p ", +" %a %d-%b-%Y %H%M%S ", +" %a %d-%b-%Y %I%M %p ", +" %a %d-%b-%Y %H%M ", +" %I:%M:%S %p %a %d-%b-%Y ", +" %H:%M:%S %a %d-%b-%Y ", +" %I:%M %p %a %d-%b-%Y ", +" %H:%M %a %d-%b-%Y ", +" %I%M%S %p %a %d-%b-%Y ", +" %H%M%S %a %d-%b-%Y ", +" %I%M %p %a %d-%b-%Y ", +" %H%M %a %d-%b-%Y ", + +/* Wed 31/Dec/1969 */ +" %a %d/%b/%Y %I:%M:%S %p ", +" %a %d/%b/%Y %H:%M:%S ", +" %a %d/%b/%Y %I:%M %p ", +" %a %d/%b/%Y %H:%M ", +" %a %d/%b/%Y %I%M%S %p ", +" %a %d/%b/%Y %H%M%S ", +" %a %d/%b/%Y %I%M %p ", +" %a %d/%b/%Y %H%M ", +" %I:%M:%S %p %a %d/%b/%Y ", +" %H:%M:%S %a %d/%b/%Y ", +" %I:%M %p %a %d/%b/%Y ", +" %H:%M %a %d/%b/%Y ", +" %I%M%S %p %a %d/%b/%Y ", +" %H%M%S %a %d/%b/%Y ", +" %I%M %p %a %d/%b/%Y ", +" %H%M %a %d/%b/%Y ", + +/* Wed, 31 Dec 1969 */ +" %a, %d %b %Y %I:%M:%S %p ", +" %a, %d %b %Y %H:%M:%S ", +" %a, %d %b %Y %I:%M %p ", +" %a, %d %b %Y %H:%M ", +" %a, %d %b %Y %I%M%S %p ", +" %a, %d %b %Y %H%M%S ", +" %a, %d %b %Y %I%M %p ", +" %a, %d %b %Y %H%M ", +" %I:%M:%S %p %a, %d %b %Y ", +" %H:%M:%S %a, %d %b %Y ", +" %I:%M %p %a, %d %b %Y ", +" %H:%M %a, %d %b %Y ", +" %I%M%S %p %a, %d %b %Y ", +" %H%M%S %a, %d %b %Y ", +" %I%M %p %a, %d %b %Y ", +" %H%M %a, %d %b %Y ", + +/* Wed, 31-Dec-1969 */ +" %a, %d-%b-%Y %I:%M:%S %p ", +" %a, %d-%b-%Y %H:%M:%S ", +" %a, %d-%b-%Y %I:%M %p ", +" %a, %d-%b-%Y %H:%M ", +" %a, %d-%b-%Y %I%M%S %p ", +" %a, %d-%b-%Y %H%M%S ", +" %a, %d-%b-%Y %I%M %p ", +" %a, %d-%b-%Y %H%M ", +" %I:%M:%S %p %a, %d-%b-%Y ", +" %H:%M:%S %a, %d-%b-%Y ", +" %I:%M %p %a, %d-%b-%Y ", +" %H:%M %a, %d-%b-%Y ", +" %I%M%S %p %a, %d-%b-%Y ", +" %H%M%S %a, %d-%b-%Y ", +" %I%M %p %a, %d-%b-%Y ", +" %H%M %a, %d-%b-%Y ", + +/* Wed, 31/Dec/1969 */ +" %a, %d/%b/%Y %I:%M:%S %p ", +" %a, %d/%b/%Y %H:%M:%S ", +" %a, %d/%b/%Y %I:%M %p ", +" %a, %d/%b/%Y %H:%M ", +" %a, %d/%b/%Y %I%M%S %p ", +" %a, %d/%b/%Y %H%M%S ", +" %a, %d/%b/%Y %I%M %p ", +" %a, %d/%b/%Y %H%M ", +" %I:%M:%S %p %a, %d/%b/%Y ", +" %H:%M:%S %a, %d/%b/%Y ", +" %I:%M %p %a, %d/%b/%Y ", +" %H:%M %a, %d/%b/%Y ", +" %I%M%S %p %a, %d/%b/%Y ", +" %H%M%S %a, %d/%b/%Y ", +" %I%M %p %a, %d/%b/%Y ", +" %H%M %a, %d/%b/%Y ", + +/* Dec 31, 1969 */ +" %b %d, %Y %I:%M:%S %p ", +" %b %d, %Y %H:%M:%S ", +" %b %d, %Y %I:%M %p ", +" %b %d, %Y %H:%M ", +" %b %d, %Y %I%M%S %p ", +" %b %d, %Y %H%M%S ", +" %b %d, %Y %I%M %p ", +" %b %d, %Y %H%M ", +" %I:%M:%S %p %b %d, %Y ", +" %H:%M:%S %b %d, %Y ", +" %I:%M %p %b %d, %Y ", +" %H:%M %b %d, %Y ", +" %I%M%S %p %b %d, %Y ", +" %H%M%S %b %d, %Y ", +" %I%M %p %b %d, %Y ", +" %H%M %b %d, %Y ", + +/* Dec-31-1969 */ +" %b-%d-%Y %I:%M:%S %p ", +" %b-%d-%Y %H:%M:%S ", +" %b-%d-%Y %I:%M %p ", +" %b-%d-%Y %H:%M ", +" %b-%d-%Y %I%M%S %p ", +" %b-%d-%Y %H%M%S ", +" %b-%d-%Y %I%M %p ", +" %b-%d-%Y %H%M ", +" %I:%M:%S %p %b-%d-%Y ", +" %H:%M:%S %b-%d-%Y ", +" %I:%M %p %b-%d-%Y ", +" %H:%M %b-%d-%Y ", +" %I%M%S %p %b-%d-%Y ", +" %H%M%S %b-%d-%Y ", +" %I%M %p %b-%d-%Y ", +" %H%M %b-%d-%Y ", + +/* Dec/31/1969 */ +" %b/%d/%Y %I:%M:%S %p ", +" %b/%d/%Y %H:%M:%S ", +" %b/%d/%Y %I:%M %p ", +" %b/%d/%Y %H:%M ", +" %b/%d/%Y %I%M%S %p ", +" %b/%d/%Y %H%M%S ", +" %b/%d/%Y %I%M %p ", +" %b/%d/%Y %H%M ", +" %I:%M:%S %p %b/%d/%Y ", +" %H:%M:%S %b/%d/%Y ", +" %I:%M %p %b/%d/%Y ", +" %H:%M %b/%d/%Y ", +" %I%M%S %p %b/%d/%Y ", +" %H%M%S %b/%d/%Y ", +" %I%M %p %b/%d/%Y ", +" %H%M %b/%d/%Y ", + +/* Wed Dec 31, 1969 */ +" %a %b %d, %Y %I:%M:%S %p ", +" %a %b %d, %Y %H:%M:%S ", +" %a %b %d, %Y %I:%M %p ", +" %a %b %d, %Y %H:%M ", +" %a %b %d, %Y %I%M%S %p ", +" %a %b %d, %Y %H%M%S ", +" %a %b %d, %Y %I%M %p ", +" %a %b %d, %Y %H%M ", +" %I:%M:%S %p %a %b %d, %Y ", +" %H:%M:%S %a %b %d, %Y ", +" %I:%M %p %a %b %d, %Y ", +" %H:%M %a %b %d, %Y ", +" %I%M%S %p %a %b %d, %Y ", +" %H%M%S %a %b %d, %Y ", +" %I%M %p %a %b %d, %Y ", +" %H%M %a %b %d, %Y ", + +/* Wed Dec-31-1969 */ +" %a %b-%d-%Y %I:%M:%S %p ", +" %a %b-%d-%Y %H:%M:%S ", +" %a %b-%d-%Y %I:%M %p ", +" %a %b-%d-%Y %H:%M ", +" %a %b-%d-%Y %I%M%S %p ", +" %a %b-%d-%Y %H%M%S ", +" %a %b-%d-%Y %I%M %p ", +" %a %b-%d-%Y %H%M ", +" %I:%M:%S %p %a %b-%d-%Y ", +" %H:%M:%S %a %b-%d-%Y ", +" %I:%M %p %a %b-%d-%Y ", +" %H:%M %a %b-%d-%Y ", +" %I%M%S %p %a %b-%d-%Y ", +" %H%M%S %a %b-%d-%Y ", +" %I%M %p %a %b-%d-%Y ", +" %H%M %a %b-%d-%Y ", + +/* Wed Dec/31/1969 */ +" %a %b/%d/%Y %I:%M:%S %p ", +" %a %b/%d/%Y %H:%M:%S ", +" %a %b/%d/%Y %I:%M %p ", +" %a %b/%d/%Y %H:%M ", +" %a %b/%d/%Y %I%M%S %p ", +" %a %b/%d/%Y %H%M%S ", +" %a %b/%d/%Y %I%M %p ", +" %a %b/%d/%Y %H%M ", +" %I:%M:%S %p %a %b/%d/%Y ", +" %H:%M:%S %a %b/%d/%Y ", +" %I:%M %p %a %b/%d/%Y ", +" %H:%M %a %b/%d/%Y ", +" %I%M%S %p %a %b/%d/%Y ", +" %H%M%S %a %b/%d/%Y ", +" %I%M %p %a %b/%d/%Y ", +" %H%M %a %b/%d/%Y ", + +/* Wed, Dec 31, 1969 */ +" %a, %b %d, %Y %I:%M:%S %p ", +" %a, %b %d, %Y %H:%M:%S ", +" %a, %b %d, %Y %I:%M %p ", +" %a, %b %d, %Y %H:%M ", +" %a, %b %d, %Y %I%M%S %p ", +" %a, %b %d, %Y %H%M%S ", +" %a, %b %d, %Y %I%M %p ", +" %a, %b %d, %Y %H%M ", +" %I:%M:%S %p %a, %b %d, %Y ", +" %H:%M:%S %a, %b %d, %Y ", +" %I:%M %p %a, %b %d, %Y ", +" %H:%M %a, %b %d, %Y ", +" %I%M%S %p %a, %b %d, %Y ", +" %H%M%S %a, %b %d, %Y ", +" %I%M %p %a, %b %d, %Y ", +" %H%M %a, %b %d, %Y ", + +/* Wed, Dec-31-1969 */ +" %a, %b-%d-%Y %I:%M:%S %p ", +" %a, %b-%d-%Y %H:%M:%S ", +" %a, %b-%d-%Y %I:%M %p ", +" %a, %b-%d-%Y %H:%M ", +" %a, %b-%d-%Y %I%M%S %p ", +" %a, %b-%d-%Y %H%M%S ", +" %a, %b-%d-%Y %I%M %p ", +" %a, %b-%d-%Y %H%M ", +" %I:%M:%S %p %a, %b-%d-%Y ", +" %H:%M:%S %a, %b-%d-%Y ", +" %I:%M %p %a, %b-%d-%Y ", +" %H:%M %a, %b-%d-%Y ", +" %I%M%S %p %a, %b-%d-%Y ", +" %H%M%S %a, %b-%d-%Y ", +" %I%M %p %a, %b-%d-%Y ", +" %H%M %a, %b-%d-%Y ", + +/* Wed, Dec/31/1969 */ +" %a, %b/%d/%Y %I:%M:%S %p ", +" %a, %b/%d/%Y %H:%M:%S ", +" %a, %b/%d/%Y %I:%M %p ", +" %a, %b/%d/%Y %H:%M ", +" %a, %b/%d/%Y %I%M%S %p ", +" %a, %b/%d/%Y %H%M%S ", +" %a, %b/%d/%Y %I%M %p ", +" %a, %b/%d/%Y %H%M ", +" %I:%M:%S %p %a, %b/%d/%Y ", +" %H:%M:%S %a, %b/%d/%Y ", +" %I:%M %p %a, %b/%d/%Y ", +" %H:%M %a, %b/%d/%Y ", +" %I%M%S %p %a, %b/%d/%Y ", +" %H%M%S %a, %b/%d/%Y ", +" %I%M %p %a, %b/%d/%Y ", +" %H%M %a, %b/%d/%Y ", diff --git a/src/datetime.c b/src/datetime.c index f39f80c..74ef2d3 100644 --- a/src/datetime.c +++ b/src/datetime.c @@ -1,7 +1,27 @@ +/* + * Copyright (C) 2021 P. J. McDermott + * + * This file is part of @ + * + * @ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with @. If not, see <http://www.gnu.org/licenses/>. + */ + #define _XOPEN_SOURCE #include <ctype.h> #include <errno.h> +#include <limits.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -10,42 +30,22 @@ #include "datetime.h" static const char *DATETIME_FMTS_[] = { - "%H:%M:%S", - "%I:%M:%S %p", - "%H:%M", - "%Y-%m-%dT%H:%M:%S", - "%Y-%m-%d %H:%M:%S", - "%A %B %d, %Y %H:%M:%S", +#include "datetime-formats.c" NULL }; static char * -datetime_normalize_spacing(int argc, const char *argv[]) +datetime_concat_args(int argc, const char *argv[]) { int buf_l; int i; - int l; - bool was_space; - int j; char *buf; int buf_i; + int j; buf_l = 0; for (i = 0; i < argc; ++i) { - l = strlen(argv[i]); - was_space = true; - for (j = 0; j < l; ++j) { - if (isspace(argv[i][j]) != 0) { - if (was_space == false) { - buf_l++; - was_space = true; - } - } else { - buf_l++; - was_space = false; - } - } - ++buf_l; + buf_l += strlen(argv[i]) + 1; } buf = calloc(buf_l, sizeof(*buf)); @@ -57,18 +57,8 @@ datetime_normalize_spacing(int argc, const char *argv[]) buf_i = 0; for (i = 0; i < argc; ++i) { - l = strlen(argv[i]); - was_space = true; - for (j = 0; j < l; ++j) { - if (isspace(argv[i][j]) != 0) { - if (was_space == false) { - buf[buf_i++] = ' '; - was_space = true; - } - } else { - buf[buf_i++] = argv[i][j]; - was_space = false; - } + for (j = 0; argv[i][j] != '\0'; ++j) { + buf[buf_i++] = argv[i][j]; } buf[buf_i++] = ' '; } @@ -78,27 +68,58 @@ datetime_normalize_spacing(int argc, const char *argv[]) } int -datetime_parse(int argc, const char *argv[], struct tm *tm) +datetime_parse(int argc, const char *argv[], struct tm *arg_tm) { - int e = -1; - char *buf; - int i; - char *end; + char *buf; + int i; + char *end; + time_t arg_sec; + time_t now_sec; + struct tm *now_tm; - buf = datetime_normalize_spacing(argc, argv); + buf = datetime_concat_args(argc, argv); if (buf == NULL) { return -1; } + arg_tm->tm_mday = INT_MIN; /* Sentinel */ + arg_tm->tm_sec = 0; /* Default */ + for (i = 0; DATETIME_FMTS_[i] != NULL; ++i) { - printf("%s =~ %s\n", buf, DATETIME_FMTS_[i]); - end = strptime(buf, DATETIME_FMTS_[i], tm); + /* printf("%s =~ %s\n", buf, DATETIME_FMTS_[i]); */ + end = strptime(buf, DATETIME_FMTS_[i], arg_tm); if (end != NULL && *end == '\0') { - e = 0; - break; + goto found; + } + } + + free(buf); + fprintf(stderr, "Unknown date format\n"); + return -1; + + found: + /* TODO: Support %a-only dates and optional years */ + if (arg_tm->tm_mday == INT_MIN) { + /* No date specified; try today. */ + now_sec = time(NULL); + now_tm = localtime(&now_sec); + arg_tm->tm_year = now_tm->tm_year; + arg_tm->tm_mon = now_tm->tm_mon; + arg_tm->tm_mday = now_tm->tm_mday; + arg_sec = mktime(arg_tm); + if (arg_sec <= mktime(now_tm)) { + /* Specified time already happened today; use tomorrow. + * Adding the number of seconds in a day is a shortcut + * that ignores leap seconds. One better method would + * be to increment tm_mday % days in tm_mon, etc. */ + arg_sec += 60 * 60 * 24; + now_tm = localtime(&arg_sec); + arg_tm->tm_year = now_tm->tm_year; + arg_tm->tm_mon = now_tm->tm_mon; + arg_tm->tm_mday = now_tm->tm_mday; } } free(buf); - return e; + return 0; } diff --git a/src/datetime.h b/src/datetime.h index 562b377..057bc4b 100644 --- a/src/datetime.h +++ b/src/datetime.h @@ -1,4 +1,26 @@ +/* + * Copyright (C) 2021 P. J. McDermott + * + * This file is part of @ + * + * @ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with @. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DATETIME_H_ +#define DATETIME_H_ int datetime_parse(int argc, const char *argv[], struct tm *tm); +#endif /* DATETIME_H_ */ diff --git a/src/local.mk b/src/local.mk index 0882580..223a4a2 100644 --- a/src/local.mk +++ b/src/local.mk @@ -2,3 +2,6 @@ %reldir%/datetime.c \ %reldir%/datetime.h \ %reldir%/main.c + +EXTRA_DIST += \ + %reldir%/datetime-formats.c @@ -1,16 +1,39 @@ +/* + * Copyright (C) 2021 P. J. McDermott + * + * This file is part of @ + * + * @ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * @ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with @. If not, see <http://www.gnu.org/licenses/>. + */ + #include <stdio.h> +#include <stdlib.h> #include <time.h> #include "datetime.h" int -main(int argc, char *argv[]) +main(int argc, const char *argv[]) { struct tm tm; - datetime_parse(argc - 1, argv + 1, &tm); + if (datetime_parse(argc - 1, argv + 1, &tm) < 0) { + return EXIT_FAILURE; + } + printf("%d-%02d-%02dT%02d:%02d:%02d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - return 0; + return EXIT_SUCCESS; } |