how to calculate time duration from two date/time values using jq

Viewed 1487

I have some json that looks like this....

[
  {
    "start": "20200629T202456Z",
    "end": "20200629T211459Z",
    "tags": [
      "WPP",
      "WPP review tasks, splashify popup",
      "clients",
      "work"
    ],
    "annotation": "update rules, fix drush errors, create base wpp-splash module."
  },
  {
    "start": "20200629T223000Z",
    "end": "20200629T224641Z",
    "tags": [
      "WPP",
      "WPP review tasks, splashify popup",
      "clients",
      "work"
    ]
  },
 ]

and I want to show a duration of hours:minutes instead of "start" and "end" times.

The time format might be a little unusual(?), it's coming from timewarrior. I imagine this would be easier for jq to accomplish if the date/time were stored in a normal unix timestamp, but maybe this is still possible? Could jq write the output like

[
  {
    "time": "0:50:03",
    "tags": [
      "WPP",
      "WPP review tasks, splashify popup",
      "clients",
      "work"
    ],
    "annotation": "update rules, fix drush errors, create base wpp-splash module."
  }
]

or something similar.

Is that possible?

1 Answers

For clarity, let's define a helper function:

def duration($finish; $start):
  def twodigits: "00" + tostring | .[-2:];
  [$finish, $start]
  | map(strptime("%Y%m%dT%H%M%SZ") | mktime) # seconds
  | .[0] - .[1]
  | (. % 60 | twodigits) as $s
  | (((. / 60) % 60) | twodigits)  as $m
  | (./3600 | floor) as $h
  | "\($h):\($m):\($s)" ;

The solution is now simply:

map( {time: duration(.end;.start)} + del(.start,.end) )
Related