Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jq filter json by dates

Tags:

json

jq

I have some json that looks like this

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

I want to return ids that the last login date is > 90days so in this case it should only return 9376. I am thinking I need to use fromdateiso8601 in combination with a select but am having a little trouble getting the syntax right.

This seems to work

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

but I still get

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

how do I deal with the null, ideally those would be included in the results.

like image 971
Jeffrey Ellin Avatar asked Oct 05 '16 18:10

Jeffrey Ellin


2 Answers

Just add the appropriate null checks.

.users[] | select (.last_login | . == null or fromdateiso8601 > 1475625600).id 
like image 198
Jeff Mercado Avatar answered Oct 23 '22 07:10

Jeff Mercado


One way to protect against null values of .last_login would be as follows:

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

For clarity, though, I'd add parentheses, e.g.:

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

Or more defensively still, use ?:

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

If you want to include items for which .last_login evaluates to null, then you could use the filter that Jeff suggested, or perhaps:

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

P.S. For "90 days before now, expressed in seconds since the beginning of the Unix epoch", you could use:

def daysAgo(days):  (now | floor) - (days * 86400);
like image 5
peak Avatar answered Oct 23 '22 06:10

peak