jq фильтрует json по датам

#json #jq

#json #jq

Вопрос:

У меня есть некоторый json, который выглядит следующим образом

  {
  "users":[ {  
     "id":8734,
     "last_login":"2016-10-04T06:59:40Z"
  },
  {  
    "id":9376,
    "last_login":"2016-05-04T20:37:32Z"
  },
  {  
    "id":9376,
    "last_login":null
  }
]}
  

Я хочу вернуть идентификаторы, что дата последнего входа в систему> 90 дней, поэтому в этом случае он должен возвращать только 9376. Я думаю, мне нужно использовать fromdateiso8601 в сочетании с select, но у меня возникли небольшие проблемы с правильным синтаксисом.

Кажется, это работает

 .users[] | select ( .last_login | fromdateiso8601 > 1475625600) | .id 
  

но я все равно получаю

 jq: error (at <stdin>:0): strptime/1 requires string inputs and arguments
  

как мне справиться с нулевым значением, в идеале они должны быть включены в результаты.

Ответ №1:

Просто добавьте соответствующие нулевые проверки.

 .users[] | select (.last_login | . == null or fromdateiso8601 > 1475625600).id 
  

Комментарии:

1. Джефф — разве это не должно быть and ?

2. На самом деле я имел в виду, что это должно быть an or , но у меня было неправильное первое условие. Он упомянул, что мы хотели включить результаты со null значениями.

Ответ №2:

Один из способов защиты от нулевых значений .last_login заключается в следующем:

 .users[]
| select ( .last_login // empty | fromdateiso8601 > 1475625600)
| .id 
  

Однако для ясности я бы добавил круглые скобки, например::

 .users[]
| select ( (.last_login // empty) | fromdateiso8601 > 1475625600)
| .id 
  

Или, что еще более важно, используйте ? :

 .users[]
| select ( .last_login | fromdateiso8601? > 1475625600)
| .id 
  

Если вы хотите включить элементы, для которых .last_login вычисляется null , тогда вы можете использовать фильтр, предложенный Джеффом, или, возможно:

  (.last_login | fromdateiso8601? > 1475625600) // true
  

PS Для «90 дней до настоящего времени, выраженных в секундах с начала эпохи Unix», вы могли бы использовать:

 def daysAgo(days):  (now | floor) - (days * 86400);