Diferencia horaria entre dos fechas ISO8601 con fracción de segundo

Diferencia horaria entre dos fechas ISO8601 con fracción de segundo

Recibo las siguientes marcas de tiempo de Alpine Linux:

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

¿Cómo los decodifico y sé cuánto tiempo ha pasado entre ellos?

La pregunta vinculada habla de una época, mientras que aquí claramente no lo es.

Respuesta1

En sistemas GNU:

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

Le daría la diferencia horaria como un número de segundos en coma flotante.

Advertencia: el número se proporcionará utilizando un punto ( .) como separador decimal incluso en lugares donde sea la coma ( ,).

Podrías canalizar esa salida para tr . "$(locale decimal_point)"solucionarlo.

O, con zsh, podrías hacer:

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

en su lugar, le dará un número con el separador decimal correcto en su localidad.

Sin embargo, dado que zshutiliza el doubleformato numérico de su procesador, es posible que proporcione un número diferente a medida que los números 1493104793.946109551alcanzan el límite de precisión de esos números. bcno tiene el problema ya que utiliza precisión arbitraria.

zshtiene capacidades de análisis de tiempo integradas, por lo que también se puede escribir una solución que funcione en sistemas que no sean GNU como:

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))

información relacionada