jq icon indicating copy to clipboard operation
jq copied to clipboard

Converting non-iso8601 datetime strings to epoch (mktime) format

Open luckman212 opened this issue 2 years ago • 4 comments

Version

jq-1.7.1

Problem

I am working with an API that outputs dates in this format:

{
  "lastSeen": "2024-02-19T17:37:01-05:00",
  "lastConnectionDurationS": 190.612964
}

I'm trying to parse that lastSeen string into epoch time, something like

$ jq '.lastSeen | strptime("%Y-%m-%dT%H:%M:%S-05:00") | mktime'
1708364221

I am looking for a more generalized function that can accept a date formatted in this way and turn it into the correct epoch time integer. My jq-fu isn't up to the challenge. Was wondering if anyone had ideas. I've read the related links below.

Related

  • https://jqlang.github.io/jq/manual/#dates
  • https://github.com/jqlang/jq/issues/1053

luckman212 avatar Feb 19 '24 22:02 luckman212

fromdate would do it if only your datetime strings had a "Z" at the end, so you could (.lastSeen + "Z")|fromdate.

nicowilliams avatar Feb 20 '24 20:02 nicowilliams

Thanks, but because of the -05:00, I get this:

$ echo '{ "lastSeen": "2024-02-19T17:37:01-05:00" }' | jq '.lastSeen + "Z" | fromdate'
jq: error (at <stdin>:1): date "2024-02-19T17:37:01-05:00Z" does not match format "%Y-%m-%dT%H:%M:%SZ"

luckman212 avatar Feb 20 '24 22:02 luckman212

Oh, sorry, I went too quick and missed the time zone offset.

You can use the %z format specifier:

$ jq -n '"2024-02-19T17:37:01-05:00" | strptime("%Y-%m-%dT%H:%M:%S%z") | mktime'
1708364221

However, %z requires that the : not be present in the time zone offset, so you might have to remove it:

$ jq -n '("2024-02-19T17:37:01"|length) as $n | "2024-02-19T17:37:01-05:00" as $t | ($t[0:$n] + $t[$n:$n+3] + $t[$n+4:$n+6]) | strptime("%Y-%m-%dT%H:%M:%S%z") | mktime'
1708364221

nicowilliams avatar Feb 20 '24 22:02 nicowilliams

Thank you. That works! Here are some other variants that seem to work also

$ jq -n '"2024-02-19T17:37:01-05:00" as $o | $o[-6:] as $tz | $tz|sub(":";"") as $ntz | $o|sub($tz;$ntz) | strptime("%Y-%m-%dT%H:%M:%S%z") | mktime'
1708364221
$ jq -n '"2024-02-19T17:37:01-05:00" | gsub(":(?=[0-9]{2}$)";"") | strptime("%Y-%m-%dT%H:%M:%S%z") | mktime'
1708364221

luckman212 avatar Feb 20 '24 23:02 luckman212