Overall aim: Parse a string in GMT as a time using jq and output both a formatted time and the difference of that time to "now". However, jqs (version 1.6, Debian testing) timezone handling seems very confused to me:
$ jq --version
jq-1.6
$ date
Sa 4. Jul 19:36:08 BST 2020
$ echo '""' | jq 'now | strftime("%H:%M")'
"18:36" // OK, strftime is supposed to give GMT
$ echo '""' | jq 'now | strflocaltime("%H:%M")'
"19:36" // also OK, British Summer time is one hour ahead, strflocaltime should give local time
$ echo '"2020-07-04T18:14:12Z"' | jq 'strptime("%Y-%m-%dT%H:%M:%SZ") | strftime("%H:%M")'
"18:14" // strptime parses GMT, so this is fine
$ echo '"2020-07-04T18:14:12Z"' | jq 'strptime("%Y-%m-%dT%H:%M:%SZ") | strflocaltime("%H:%M")'
"18:14" // but why is this not 19:14?!
$ echo '"2020-07-04T18:14:12Z"' | jq 'strptime("%Y-%m-%dT%H:%M:%SZ") | mktime | strftime("%H:%M")'
"19:14" // and why does "mktime" change things around?
$ echo '"2020-07-04T18:14:12Z"' | jq 'strptime("%Y-%m-%dT%H:%M:%SZ") | mktime | strflocaltime("%H:%M")'
"20:14" // and why does strflocaltime kick in after, but not before mktime?
$ echo '"2020-07-04T18:14:12Z"' | jq 'fromdate | strftime("%H:%M")'
"19:14" // I thought fromdate was synonymous to strptime?
$ echo '"2020-07-04T18:14:12Z"' | jq 'fromdate | strflocaltime("%H:%M")'
"20:14" // I suppose this is the same issue as above with mktime
Longer version: I'm playing around with an API to get a little display of arrival times at a nearby train station, in particular I want to show the next few trains and how many minutes from now they will leave. I want to use jq to parse that data. The data contains time strings of the format "2020-07-04T18:14:12Z". My understanding is that both fromdate and strptime in jq should parse that data as a GMT time stamp (from the man page: "In all cases these builtins deal exclusively with time in UTC.", the manpage seems to use GMT and UTC interchangeably) and any operations within jq use UTC, with only final output being in the local timezone if strflocaltime is used.
However, this understanding must be wrong, given the output of jq with various inputs shown above. In particular, I do not understand how to properly and reliably parse a time string as a GMT time stamp and b) once that is done, how the outputs of fromdate, mktime, now and strptime respectively differ when passed into strf[local]time to produce the array of outputs seen above.
Edit: Playing around further and with the information from the first two answers, it appears that the main problem is fromdate's application (or not) of Daylight Savings Time depending on the setting of the TZ environment variable:
$ TZ=BST jq -n '"2020-07-05T07:38:57Z" | fromdate'
1593934737
$ TZ=Etc/UTC jq -n '"2020-07-05T07:38:57Z" | fromdate'
1593934737
$ TZ=Europe/London jq -n '"2020-07-05T07:38:57Z" | fromdate'
1593938337
$ TZ=Asia/Tokyo jq -n '"2020-07-05T07:38:57Z" | fromdate'
1593934737
$ TZ=America/Los_Angeles jq -n '"2020-07-05T07:38:57Z" | fromdate'
1593938337
$ TZ=Asia/Kathmandu jq -n '"2020-07-05T07:38:57Z" | fromdate'
1593934737
$ unset TZ; jq -n '"2020-07-05T07:38:57Z" | fromdate'
1593938337
Note that London, Los Angeles and the unset TZ get a different Unix epoch timestamp than Tokyo, Kathmandu, UTC and the (I think malformed?) BST. I believe this should not happen, as timestamps should be timezone-independent. Unfortunately at the moment it appears to disregard the permanent timezone offset (Tokyo and Kathmandu give the same result as UTC, neither of the two have DST) but it does take into account DST unless running in a timezone which does not observe DST.
strflocaltime, when given a time stamp, seems to apply permanent and DST timezone corrections depending on the current value of TZ.
Unfortunately this seems to imply that I first need to set TZ to Etc/Utc to get fromdate to behave correctly and then when I want to print the local time, I need to re-set TZ to the local timezone.