date,touch: allow timezone offsets in dates

Allow ISO 8601 style dates to include a timezone offset.  Like
the '@' format these dates aren't relative to the user's current
timezone and shouldn't be subject to DST adjustment.

- The implementation uses the strptime() '%z' format specifier.
  This an extension which may not be available so the use of
  timezones is a configuration option.

- The 'touch' applet has been updated to respect whether DST
  adjustment is required, matching 'date'.

function                                             old     new   delta
parse_datestr                                        624     730    +106
static.fmt_str                                       106     136     +30
touch_main                                           388     392      +4
date_main                                            818     819      +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 141/0)             Total: 141 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Ron Yorston
2021-09-16 10:26:14 +01:00
committed by Denys Vlasenko
parent 83e20cb81c
commit 9fe1548bbf
6 changed files with 83 additions and 10 deletions

View File

@@ -266,6 +266,7 @@ int date_main(int argc UNUSED_PARAM, char **argv)
/* If date string is given, update tm_time, and maybe set date */
if (date_str != NULL) {
int check_dst = 1;
/* Zero out fields - take her back to midnight! */
tm_time.tm_sec = 0;
tm_time.tm_min = 0;
@@ -276,12 +277,12 @@ int date_main(int argc UNUSED_PARAM, char **argv)
if (strptime(date_str, fmt_str2dt, &tm_time) == NULL)
bb_error_msg_and_die(bb_msg_invalid_date, date_str);
} else {
parse_datestr(date_str, &tm_time);
check_dst = parse_datestr(date_str, &tm_time);
}
/* Correct any day of week and day of year etc. fields */
/* Be sure to recheck dst (but not if date is time_t format) */
if (date_str[0] != '@')
/* Be sure to recheck dst (but not if date is UTC) */
if (check_dst)
tm_time.tm_isdst = -1;
ts.tv_sec = validate_tm_time(date_str, &tm_time);
ts.tv_nsec = 0;