¿Cuál es un comando estándar para imprimir una fecha en formato RFC-3339?

19

El datecomando no ofrece tal cosa, lo cual es un poco triste ya que RFC-3339 es el formato moderno, generalizado y sensato utilizado en todas partes (excepto en el correo electrónico que no es ni moderno ni sensato).

Mi desplazamiento de zona horaria es actualmente -08: 00, por lo que la forma más simple de este comando debería imprimir la hora actual como 2013-09-05T14:58:33.102-08:00.

Martin Jambon
fuente
¿Qué estándar (es) le interesa?
Stéphane Chazelas
Personalmente estoy bien con GNU, pero en el gran esquema de cosas realmente debería ser más amplio que eso. También debe venir con un valor predeterminado razonable (opción corta, precisión de milisegundos) y tener una forma de especificar la precisión del subsegundo (número de dígitos que no sean 0 o 9).
Martin Jambon
1
Es no un formato cuerdo: la ausencia total de espacio en blanco hace que sea innecesariamente difícil para los seres humanos para leer. Debe usar la ligera variación, 2013-09-05 14:58:33.102 -0800excepto cuando hay alguna razón por la cual no se deben usar espacios en absoluto.
zwol
1
Lo estaba comparando con el formato de fecha de correo (RFC 822, 2822) que es difícil de leer tanto para humanos como para máquinas.
Martin Jambon

Respuestas:

30

Parece que se puede hacer varios formatos usando el interruptor en la implementación GNU de date(versión 5.90 o superior), --rfc3339=.

Ejemplos

$ date --rfc-3339=date
2014-03-19

$ date --rfc-3339=seconds
2014-03-19 18:00:05-04:00

$ date --rfc-3339=ns
2014-03-19 18:00:08.179780629-04:00

Si desea Tque se agregue, como un truco:

$ date --rfc-3339=seconds | sed 's/ /T/'
2014-03-19T18:35:03-04:00

Si lo quieres en milisegundos:

$ date --rfc-3339=ns | sed 's/ /T/; s/\(\....\).*\([+-]\)/\1\2/g'
2014-03-19T18:42:52.362-04:00

Referencias

slm
fuente
77
En estos días, no se necesita hack para obtener la 'T'. El --iso-8601' option accepts the same arguments as --rfc-3339`, e incluye la 'T' en su salida.
Ti Strga
1
La parte de Sed s/\(\....\).*-/\1-/gdebería ser s/\(\....\).*\([+-]\)/\1\2/gtrabajar también al este del Atlántico.
svante
1
@svante: gracias por el detalle, arreglado.
slm
2
@Eonil que en realidad no es correcto, el RFC3339 establece: NOTE: ISO 8601 defines date and time separated by "T".Mientras que RFC3339 le permite usar un espacio en su lugar. Lea ietf.org/rfc/rfc3339.txt Sección 5.6
rwenz3l
1
@ rwenz3l Mi culpa. Acabo de leer solo la parte ABNF y me perdí las notas. ¡Gracias por mencionarlo!
Eonil
18

Con GNU date(5.90 o superior):

$ TZ=America/Anchorage date '+%FT%T.%N%:z'
2014-03-19T14:29:31.041119357-08:00

Reemplazar %Ncon %3Nde milisegundos, %6Npara micro-segundos ...

AFAIK, ninguna de las especificaciones POSIX, Unix o LSB especifican ningún comando que pueda mostrar tiempos con granularidad inferior a un segundo, pero la parte fraccional es opcional en RFC 3339.

POSIX / Unix / LSB strftime admite %zmostrar el desplazamiento TZ como -0800, por lo que el más portátil que probablemente obtendrá es:

 $ TZ=America/Anchorage perl -MPOSIX -le '$t = strftime "%Y-%m-%dT%T%z",
   localtime; $t =~ s/..$/:$&/; print $t'
 2014-03-19T14:30:23-08:00
Stéphane Chazelas
fuente
8

GNU datetiene incorporado el formato ISO-8601, ¿no está tan cerca o incluso es idéntico a RFC-3339?

1065 % date --iso-8601=seconds
2014-03-19T16:51:16-0600
Bruce Ediger
fuente
ISO-8601 permite diferentes formatos de fechas y horas, pero creo que el OP está pidiendo específicamente el formato de fecha W3C "Fecha completa más horas, minutos, segundos y una fracción decimal de un segundo AAAA-MM-DDThh: mm: ss.sTZD (por ejemplo, 1997-07-16T19: 20: 30.45 + 01: 00) " - Formatos de fecha y hora W3C .
hakre
8

¿Qué tal un buen viejo:

$ date +%Y-%m-%dT%T%z
2015-10-29T14:47:06+0200
Eran Chetzroni
fuente
¿Dónde está la información de zona horaria?
Raphael Ahrens
Esto funciona tanto en Mac como en Linux 'date'
Eran Chetzroni
1
¿Qué tal milisegundos?
Martin Jambon
66
Nota rápida aquí, sin abrir el RFC, al segmento de zona horaria, 0200le faltan dos puntos, lo que puede romper algunos sistemas que lo requieren.
Mike Mackintosh
2
La nota de @ MikeMackintosh es pertinente; el resultado que se muestra aquí no es una fecha RFC 3339 legal. Se requieren dos puntos en el segmento de zona horaria para RFC 3339; vea la definición de time-numoffseten tools.ietf.org/html/rfc3339#section-5.6 .
Mark Amery
7

También puede formatear el tiempo de acuerdo con RFC3339 (ISO8601) más fácilmente:

$ date -u +"%Y-%m-%dT%H:%M:%SZ"
2016-11-08T08:52:55Z

NOTA: Este formato también se usa en Label Schema Convention RC 1.0

Daniel Andrei Mincă
fuente
Eso no es un RFC3339 válido. La respuesta de Eran de `` `fecha +% Y-% m-% dT% T% z` `es correcta y menos caracteres. Si desea en UTC, pase la bandera -u, que pondrá a cero el desplazamiento de la zona horaria.
briceburg
Con la -ubandera esta respuesta es correcta, ¿verdad?
Lassi
0
echo "Local date only:"
date '+%Y-%m-%d'
echo
echo "Local date and time:"
date '+%Y-%m-%dT%H:%M:%S%z' | sed 's@^.\{22\}@&:@'
echo
echo "UTC date and time:"
date -u '+%Y-%m-%dT%H:%M:%SZ'

Estos comandos son compatibles con POSIX, con la excepción de la %zespecificación de conversión. Sin embargo, %zes ampliamente compatible y funciona de la misma manera en Linux, MacOS, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Solaris, Minix y Haiku. También funciona con las herramientas en Busybox, Toybox y sbase (las utilidades del sistema base suckless.org). Ya que%z salidas, la zona horaria se compensa en±HHMM formato, necesitamos la sedtubería para agregar dos puntos y cambiarlo a ±HH:MM.

NOTA: El datecomando del proyecto Heirloom tiene una %zsalida incompatible : no imprime un +signo.

Lassi
fuente