0

I receive the following time stamps from Alpine Linux:

2017-04-25T07:19:53.946109551Z    
2017-04-25T07:19:53.946155414Z

How do I decode them and know how much time has passed between them?

The linked question talks about epoch time while here it's clearly not.

Peter Mortensen
  • 1,029
  • 1
  • 8
  • 10
YAKOVM
  • 111
  • 5
  • 2
    Possible duplicate of [Tool in UNIX to subtract dates](https://unix.stackexchange.com/questions/1825/tool-in-unix-to-subtract-dates) – don_crissti Apr 25 '17 at 12:18
  • @don_crissti, wrong dup. That one if for non-GNU solutions while I suppose alpine linux is a GNU system. There has do be plenty of duplicates though. See also the nano-second part here which complicates slightly – Stéphane Chazelas Apr 25 '17 at 12:20
  • @StéphaneChazelas - there's a comment by Gilles on that Q and it points to the GNU alternative. It's true that here it's a bit more complicated... – don_crissti Apr 25 '17 at 12:21
  • OP, the linked question _doesn't mention anything about epoch times_ – don_crissti Apr 25 '17 at 12:31

1 Answers1

5

On GNU systems:

d1=2017-04-25T07:19:53.946109551Z
d2=2017-04-25T07:19:53.946155414Z
printf '%s - %s\n' "$(date -d "$d2" +%s.%N)" "$(date -d "$d1" +%s.%N)" | bc

Would give you the time difference as a floating point number of seconds.

Caveat: the number will be given using period (.) as the decimal separator even in locales where it's the comma (,) instead.

You could pipe that output to tr . "$(locale decimal_point)" to fix it.

Or, with zsh, you could do:

printf '%.9f\n' $(($(date -d "$d2" +%s.%N) - $(date -d "$d1" +%s.%N)))

instead which will give you a number with the correct decimal separator in your locale.

However since then zsh uses the double number format of your processor, you may find that it gives a different number as numbers like 1493104793.946109551 reach the limit of precision of those numbers. bc doesn't have the issue as it uses arbitrary precision.

zsh has time parsing capabilities builtin, so one can also write a solution that will work on non-GNU systems like:

parse_iso8601_full() {
  local t
  typeset -Fg REPLY
  zmodload zsh/datetime
  TZ=UTC0 strftime -r -s t %Y-%m-%dT%H:%M:%S ${1%.*} &&
    REPLY=$t.${${1%Z}##*.}
}

parse_iso8601_full $d1; t1=$REPLY
parse_iso8601_full $d2; t2=$REPLY
printf '%.9f\n' $((t2 - t1))
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501