Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jq fromdate "does not match format "%Y-%m-%dT%H:%M:%SZ"

I have an example json output below, the LastAccessedDate value is as AWS outputs it when running CLI command and thus I have no control over the format of the date.

{
  "MyList": [
    {
      "Name": "MyName1",
      "LastAccessedDate": "2021-06-29T02:00:00+02:00"
    }
  ]
    
}

When trying to run a jq command to select using fromdate like this:

cat output.json | jq '.[] | .[] | select ( .LastAccessedDate | fromdate > "2021-01-01T02:00:00+02:00")'

then I get the error message: jq: error (at <stdin>:8): date "2021-06-29T02:00:00+02:00" does not match format "%Y-%m-%dT%H:%M:%SZ"

Is there anything I could do to enable me to use jq to filter the output? Would even appreciate an explanation on what may be wrong so that I can understand for future use cases.

like image 364
WarrenG Avatar asked Nov 04 '25 20:11

WarrenG


2 Answers

Here is a jq function for converting certain ISO 8601 timestamps with timezone offsets to seconds since the beginning of the Epoch, thus facilitating comparisons of timestamps with different offsets.

# Convert a timestamp with a possibly empty timezone offset to seconds since the Epoch.
# Input should be a string of the form 
# yyyy-mm-ddThh:mm:ss or yyyy-mm-ddThh:mm:ss<OFFSET>
# where <OFFSET> is Z, or has the form `+hh:mm` or `-hh:mm`.
# If no timezone offset is explicitly given, it is taken to be Z.
def datetime_to_seconds:
  if test("[-+]")
  then capture("(?<datetime>^.*T[0-9:]+)(?<s>[-+])(?<hh>[0-9]+):?(?<mm>[0-9]*)")
  | (.datetime +"Z" | fromdateiso8601) as $seconds
  | (if .s == "+" then -1 else 1 end) as $plusminus
  | ([.hh,.mm] | map(tonumber) |.[0] *= 60 | add * 60 * $plusminus) as $offset
  | ($seconds + $offset)
  else . + (if test("Z") then "" else "Z" end) | fromdateiso8601
  end;

Note that the interpretation of + or - in the offset conforms with the principle encapsulated in the example:

The following times all refer to the same moment: "18:30Z", "22:30+04", "1130−0700", and "15:00−03:30".

like image 176
peak Avatar answered Nov 07 '25 10:11

peak


One way would be to use a custom function to strip off the timezone part and format the date string to a format compatible that jq can parse.

Note that this only works when your reference and source strings are in the same timezone offset.

jq --arg ref "2021-01-01T02:00:00+02:00" '
  def c(str): str | (split("+")[0] + "Z") | fromdate ; 
  .MyList | map(select( c(.LastAccessedDate) > c($ref) ))' json

From jq Manual

The fromdate builtin parses datetime strings. Currently fromdate only supports ISO 8601 datetime strings, but in the future it will attempt to parse datetime strings in more formats.

like image 36
Inian Avatar answered Nov 07 '25 09:11

Inian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!