From 0c9eacedaae1e0d53e265a35830f6e7ebd04cc53 Mon Sep 17 00:00:00 2001 From: William Langford Date: Wed, 29 Nov 2017 20:40:36 -0500 Subject: Actually fix the strptime tests This has been a complicated issue to fix for a number of reasons. The core of it is that the behavior is different between different versions of macOS, some of which set possible-but-incorrect values. This commit addresses the issue by always using our computation for tm_wday and tm_yday on macOS. As a side-effect, strptime format strings that specify %u and %j will no longer work on macOS. --- docs/content/3.manual/manual.yml | 3 ++- src/builtin.c | 13 +++++++++++++ tests/optional.test | 5 +++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 6baa58ca..f03efcda 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -1933,7 +1933,8 @@ sections: 8601 datetime is `"%Y-%m-%dT%H:%M:%SZ"`. jq may not support some or all of this date functionality on - some systems. + some systems. In particular, the `%u` and `%j` specifiers for + `strptime(fmt)` are not supported on macOS. examples: - program: 'fromdate' diff --git a/src/builtin.c b/src/builtin.c index e709c009..c6c8c2ea 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -1313,10 +1313,23 @@ static jv f_strptime(jq_state *jq, jv a, jv b) { * day-of-week and day-of-year sentinel checks above, the worst * this can do is produce garbage. */ +#ifdef __APPLE__ + /* + * Apple has made it worse, and different versions of the OS have different + * behaviors. Some versions just don't touch the fields, but others do, and + * sometimes provide wrong answers, at that! We can't tell at compile-time + * which behavior the target system will have, so instead we always use our + * functions to set these on OS X, and document that %u and %j are + * unsupported on OS X. + */ + set_tm_wday(&tm); + set_tm_yday(&tm); +#else if (tm.tm_wday == 8 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11) set_tm_wday(&tm); if (tm.tm_yday == 367 && tm.tm_mday != 0 && tm.tm_mon >= 0 && tm.tm_mon <= 11) set_tm_yday(&tm); +#endif jv r = tm2jv(&tm); if (*end != '\0') r = jv_array_append(r, jv_string(end)); diff --git a/tests/optional.test b/tests/optional.test index 6847ebe5..85bc9e99 100644 --- a/tests/optional.test +++ b/tests/optional.test @@ -7,9 +7,10 @@ # Check day-of-week and day of year computations # (should trip an assert if this fails) -last(range(365 * 199)|("1970-03-01T01:02:03Z"|strptime("%Y-%m-%dT%H:%M:%SZ")|mktime) + (86400 * .)|strftime("%Y-%m-%dT%H:%M:%SZ")|strptime("%Y-%m-%dT%H:%M:%SZ")) +# This date range +last(range(365 * 67)|("1970-03-01T01:02:03Z"|strptime("%Y-%m-%dT%H:%M:%SZ")|mktime) + (86400 * .)|strftime("%Y-%m-%dT%H:%M:%SZ")|strptime("%Y-%m-%dT%H:%M:%SZ")) null -[2169,0,10,1,2,3,1,9] +[2037,1,11,1,2,3,3,41] # %e is not available on mingw/WIN32 strftime("%A, %B %e, %Y") -- cgit v1.2.3