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

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

我在下面有一个示例 json 输出,LastAccessedDate 值是 AWS 在 运行ning CLI 命令时输出的值,因此我无法控制日期的格式.

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

当尝试使用 fromdate 将 jq 命令 运行 发送到 select 时,如下所示:

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

然后我收到错误消息: jq: error (at <stdin>:8): date "2021-06-29T02:00:00+02:00" does not match format "%Y-%m-%dT%H:%M:%SZ"

有什么办法可以让我使用 jq 过滤输出吗? 甚至会感谢对可能出错的解释,以便我可以理解未来的用例。

一种方法是使用自定义函数去除时区部分并将日期字符串格式化为 jq 可以解析的兼容格式。

请注意,此在您的参考字符串和源字符串处于相同时区偏移时有效。

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

来自jq手册

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.

这是一个 jq 函数,用于将某些具有时区偏移量的 ISO 8601 时间戳转换为自纪元开始以来的秒数,从而便于比较具有不同偏移量的时间戳。

# 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;

注意offset中+-的解释符合示例中封装的原理:

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