Qu'est-ce qu'une commande standard pour imprimer une date au format RFC-3339?

19

La datecommande n'offre pas une telle chose, ce qui est un peu triste puisque la RFC-3339 est le format moderne, répandu et sain utilisé partout (sauf dans le courrier électronique qui n'est ni moderne ni sain).

Mon décalage de fuseau horaire est actuellement de -08: 00, donc la forme la plus simple de cette commande devrait afficher l'heure actuelle sous la forme 2013-09-05T14:58:33.102-08:00.

Martin Jambon
la source
Quelles sont les normes qui vous intéressent?
Stéphane Chazelas
Personnellement, je vais bien avec GNU mais dans le grand schéma des choses, il devrait vraiment être plus large que cela. Il doit également être fourni avec une valeur par défaut raisonnable (option courte, précision en millisecondes) et avoir un moyen de spécifier la précision en sous-secondes (nombre de chiffres autres que 0 ou 9).
Martin Jambon
1
Ce n'est pas un format sain: l'absence totale d'espaces rend la lecture inutilement difficile pour les humains. Vous devez utiliser la légère variation, 2013-09-05 14:58:33.102 -0800sauf lorsqu'il existe une raison pour laquelle les espaces ne doivent pas être utilisés du tout.
zwol
1
Je le comparais au format de date de courrier (RFC 822, 2822) qui est difficile à lire pour les humains et les machines.
Martin Jambon

Réponses:

30

Il semble que vous pouvez faire plusieurs formats à l' aide de l'interrupteur à la mise en œuvre GNU date(version 5.90 ou plus), --rfc3339=.

Exemples

$ 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 vous souhaitez l' Tajouter, en tant que hack:

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

Si vous le souhaitez en millisecondes:

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

Les références

slm
la source
7
Ces jours-ci, aucun hack n'est nécessaire pour obtenir le «T». Le --iso-8601' option accepts the same arguments as --rfc-3339`, et inclut le «T» dans sa sortie.
Ti Strga
1
La partie s/\(\....\).*-/\1-/gdevrait être s/\(\....\).*\([+-]\)/\1\2/gde travailler également à l'est de l'Atlantique.
svante
1
@svante - merci pour le détail, corrigé.
slm
2
@Eonil qui n'est en fait pas correct, le RFC3339 déclare: NOTE: ISO 8601 defines date and time separated by "T".Alors que le RFC3339 vous permet d'utiliser un espace à la place. Lire ietf.org/rfc/rfc3339.txt Section 5.6
rwenz3l
1
@ rwenz3l Ma faute. Je viens de lire seulement la partie ABNF et j'ai raté les notes. Merci de l'avoir signalé!
Eonil
18

Avec GNU date(5,90 ou supérieur):

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

Remplacez %Npar %3Npour les millisecondes, %6Npour les micro-secondes ...

AFAIK, aucune des spécifications POSIX, Unix ou LSB ne spécifie de commande pouvant afficher les temps avec une granularité inférieure à la seconde, mais la partie fractionnaire est facultative dans la RFC 3339.

Le strftime POSIX / Unix / LSB prend %zen charge l' affichage du décalage TZ -0800, donc le plus portable que vous obtiendrez probablement est:

 $ 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
la source
8

GNU datea le format ISO-8601 intégré - n'est-ce pas assez proche ou même identique à RFC-3339?

1065 % date --iso-8601=seconds
2014-03-19T16:51:16-0600
Bruce Ediger
la source
ISO-8601 permet différents formats de dates et d'heures, mais je pense que l'OP demande spécifiquement le format de date W3C "Date complète plus heures, minutes, secondes et une fraction décimale d'une seconde AAAA-MM-JJThh: mm: ss.sTZD (par exemple 1997-07-16T19: 20: 30.45 + 01: 00) " - Formats de date et d'heure W3C .
hakre
8

Et le bon vieux:

$ date +%Y-%m-%dT%T%z
2015-10-29T14:47:06+0200
Eran Chetzroni
la source
Où sont les informations de fuseau horaire?
Raphael Ahrens
Cela fonctionne à la fois sur Mac et Linux 'date'
Eran Chetzroni
1
Que diriez-vous des millisecondes?
Martin Jambon
6
note rapide ici, sans ouvrir le RFC, le segment de fuseau horaire, 0200manque un deux-points, ce qui peut casser certains systèmes qui en ont besoin.
Mike Mackintosh
2
@ La note de MikeMackintosh est pertinente; la sortie affichée ici n'est pas une date RFC 3339 légale. Le deux-points dans le segment de fuseau horaire est requis pour RFC 3339; voir la définition de time-numoffsetat tools.ietf.org/html/rfc3339#section-5.6 .
Mark Amery
7

Vous pouvez également formater l'heure selon RFC3339 (ISO8601) plus facilement:

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

REMARQUE: ce format est également utilisé dans la Convention de schéma d'étiquette RC 1.0

Daniel Andrei Mincă
la source
Ce n'est pas un RFC3339 valide. La réponse d'Eran de `` date +% Y-% m-% dT% T% z '' est correcte et moins de caractères. Si vous voulez dans UTC passer le drapeau -u, ce qui mettra à zéro le décalage du fuseau horaire.
briceburg
Avec le -udrapeau, cette réponse est correcte, non?
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'

Ces commandes sont compatibles POSIX, à l'exception de la %zspécification de conversion. Cependant, %zest largement pris en charge et fonctionne de la même manière sous Linux, MacOS, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Solaris, Minix et Haiku. Il fonctionne également avec les outils de Busybox, Toybox et sbase (les utilitaires du système de base suckless.org). Étant donné que %zle décalage du fuseau horaire est généré au ±HHMMformat, nous avons besoin du sedcanal pour ajouter deux points et le changer en ±HH:MM.

REMARQUE: la datecommande du projet Heirloom a une %zsortie incompatible : elle n'imprime pas de +signe.

Lassi
la source