On 5/25/21 3:28 PM, Frank Liu wrote: > date doesn't seem to recognize the format with timezone info: > > bash-5.0# a="2021-05-25 19:32:36.000000000 +0000" > bash-5.0# date -d "$a" +%s > date: bad date 2021-05-25 19:32:36.000000000 +0000 > bash-5.0# /vol/debian/date -d "$a" +%s > 1621971156 > > Removing timezone +0000 works: > bash-5.0# a="2021-05-25 19:32:36.000000000" > bash-5.0# date -d "$a" +%s > 1621971156
Um, is it always 4 digits? Is there a spec on this? "man date" isn't saying. "man asciitime" isn't saying.... Ah: https://en.wikipedia.org/wiki/Time_zone#ISO_8601 https://www.youtube.com/watch?v=lg4TFV1rF0M RIGHT, +1234 +12:34 or just +12. Are we currently handling trailing Z? I don't see where we're handling trailing Z. Ok, modify parse_date() to add... ah, looks like $TZ already understands this? https://man7.org/linux/man-pages/man3/tzset.3.html There are timezones with SECONDS of offset? Ok... And it's - as well as +, so... is the space required? $ date -d "2021-05-25 19:32:36.000000000 +0000" +%s 1621971156 $ date -d "2021-05-25 19:32:36.000000000+0000" +%s 1621971156 $ date -d "2021-05-25 19:32:36.000000000+0001" +%s 1621971096 $ date -d "2021-05-25 19:32:36.000000000+00:01:37" +%s date: invalid date ‘2021-05-25 19:32:36.000000000+00:01:37’ Dear FSF: please just stop already. The tzset man page is presumably documenting what glibc does, and date reimplemented this code in an incompatible way for NO READILY APPARENT REASON... I mean you have to go out of your way to break this. $ date -d "2021-05-25 19:32:36.000000000+000137" +%s 1621965336 And THAT is just half-assing it. (How can my quick tests to see what the behavior IS be more thorough than any tests they've apparently ever DONE on this code? Don't they care?) Anyway, since the space is NOT required I can't just NULL that out to chop the existing string into two pieces. (But I'm totally cheating and null-ing out the Z at the end, and no I don't currently care that I'm modifying an environment string when I do that which will change what "ps" sees, because I'm tired and cranky.) Does it get confused by trailing whitespace? $ date -d "2021-05-25 19:32:36.000000000+000137 " +%s 1621965336 $ date -d "2021-05-25 19:32:36.000000000+ 000137" +%s 1621965336 $ date -d "2021-05-25 19:32:36.000000000+ 00 01 37" +%s date: invalid date ‘2021-05-25 19:32:36.000000000+ 00 01 37’ Sigh. Right... Ah. The reason gnu date is not using gnu libc's tz code for this is the libc code DOES NOT WORK. $ ./date -d "2021-05-25 19:32:36 +0000" +%s 1621971156 $ ./date -d "2021-05-25 19:32:36 +0001" +%s 1621971156 Elliott, do you already know this timezone stuff? My first attempt at a patch was: diff --git a/toys/posix/date.c b/toys/posix/date.c index 86c2d343..c6e0b498 100644 --- a/toys/posix/date.c +++ b/toys/posix/date.c @@ -64,27 +64,45 @@ GLOBALS( unsigned nano; ) -// Handles any leading `TZ="blah" ` in the input string. +// Handles any leading `TZ="blah" ` or trailing +#### in the input string. static void parse_date(char *str, time_t *t) { - char *new_tz = NULL, *old_tz, *s = str; + char *new = 0, *old, *s = str; if (!strncmp(str, "TZ=\"", 4)) { // Extract the time zone and skip any whitespace. - new_tz = str+4; - if (!(str = strchr(new_tz, '"'))) xvali_date(0, s); + new = str+4; + if (!(str = strchr(new, '"'))) xvali_date(0, s); // borrow error msg *str++ = 0; while (isspace(*str)) str++; + } else if ((s = strrchr(str, 'Z')) && !s[1]) { + new = "UTC"; + *s = 0; + } else { + for (s = str+strlen(str); --s>str;) if (strchr("+-", *s)) break; + if (s>str) { + for (new = s++; isspace(*s); s++); + while (isdigit(*s) || *s==':') s++; + while (isspace(*s)) s++; + if (!*s) { + s = xstrdup(new); + while (new>str && isspace(new[-1])) new--; + *new = 0; + new = s; + } else new = 0; + } + } + if (new) { // Switch $TZ. - old_tz = getenv("TZ"); - setenv("TZ", new_tz, 1); + old = getenv("TZ"); + setenv("TZ", new, 1); tzset(); } time(t); xparsedate(str, t, &TT.nano, 1); - if (new_tz) { - if (old_tz) setenv("TZ", old_tz, 1); + if (new) { + if (old) setenv("TZ", old, 1); else unsetenv("TZ"); } } But it didn't work because libc isn't playing along. What does libc want me to stick into tz for tzset? (And WHY can't tzset take an argument string?) Can I maybe just write to "extern long timezone" directly? (And always zero "daylight"?) Posix sort of implies I can: https://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html But it also sort of looks like you can specify a trailing timezone and THEN say +1234 on top of it? I'm not feeling enlightened by reading about $TZ in https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html And I already linked to the appropriate youtube video above. Rob _______________________________________________ Toybox mailing list [email protected] http://lists.landley.net/listinfo.cgi/toybox-landley.net
