Was ist ein Standardbefehl zum Drucken eines Datums im RFC-3339-Format?

17

Der dateBefehl bietet so etwas nicht an, was irgendwie traurig ist, da RFC-3339 das moderne, weitverbreitete, vernünftige Format ist, das überall verwendet wird (außer in E-Mails, die weder modern noch vernünftig sind).

Mein Zeitzonen-Offset ist derzeit -08: 00, daher sollte die einfachste Form dieses Befehls die aktuelle Zeit als ausgeben 2013-09-05T14:58:33.102-08:00.

Martin Jambon
quelle
Für welche Standards interessieren Sie sich?
Stéphane Chazelas
Mir persönlich geht es gut mit GNU, aber im Großen und Ganzen sollte es wirklich umfassender sein. Es sollte auch einen angemessenen Standardwert haben (kurze Option, Millisekundengenauigkeit) und eine Möglichkeit zum Angeben der Genauigkeit unter einer Sekunde (Anzahl der anderen Stellen als 0 oder 9).
Martin Jambon
1
Es ist kein vernünftiges Format: Das völlige Fehlen von Leerzeichen erschwert das Lesen für Menschen unnötig. Sie sollten die geringfügige Abweichung verwenden, es sei 2013-09-05 14:58:33.102 -0800denn, es gibt einen Grund, warum Leerzeichen überhaupt nicht verwendet werden dürfen.
zwol
1
Ich habe es mit dem Mail-Datumsformat (RFC 822, 2822) verglichen, das für Mensch und Maschine schwer zu lesen ist.
Martin Jambon

Antworten:

29

Es sieht so aus, als könnten Sie mit der Umstellung auf die GNU-Implementierung von date(Version 5.90 oder höher) mehrere Formate ausführen --rfc3339=.

Beispiele

$ 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

Wenn Sie möchten T, dass das als Hack hinzugefügt wird:

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

Wenn Sie es in Millisekunden wollen:

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

Verweise

slm
quelle
7
Heutzutage ist kein Hack nötig, um das 'T' zu bekommen. Das --iso-8601' option accepts the same arguments as --rfc-3339` und schließt das 'T' in seine Ausgabe ein.
Ti Strga
1
Sed Teil s/\(\....\).*-/\1-/gsollte sein s/\(\....\).*\([+-]\)/\1\2/g, auch östlich des Atlantiks zu arbeiten.
Svante
1
@svante - danke für das Detail, behoben.
slm
2
@Eonil, das tatsächlich nicht korrekt ist, gibt RFC3339 an: NOTE: ISO 8601 defines date and time separated by "T".Während RFC3339 es Ihnen ermöglicht, stattdessen ein Leerzeichen zu verwenden. Lesen Sie ietf.org/rfc/rfc3339.txt Abschnitt 5.6
rwenz3l
1
@ rwenz3l Meine Schuld. Ich habe gerade nur den ABNF-Teil gelesen und die Notizen verpasst. Vielen Dank für den Hinweis!
Eonil
18

Mit GNU date(5.90 oder höher):

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

Ersetzen %Ndurch %3Nfür Millisekunden, %6Nfür Mikrosekunden ...

In AFAIK, keiner der POSIX-, Unix- oder LSB-Spezifikationen ist ein Befehl angegeben, der Zeiten mit einer Genauigkeit von weniger als einer Sekunde anzeigen kann, der Bruchteil ist jedoch in RFC 3339 optional.

POSIX / Unix / LSB-Laufzeit unterstützt %zdie Anzeige des TZ-Offsets als -0800, daher ist das wahrscheinlich portabelste, das Sie erhalten werden:

 $ 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
quelle
8

GNU datehat das ISO-8601-Format eingebaut - ist das nicht ziemlich nah an RFC-3339?

1065 % date --iso-8601=seconds
2014-03-19T16:51:16-0600
Bruce Ediger
quelle
ISO-8601 erlaubt es, unterschiedliche Formatierungen von Daten und Zeiten, aber ich denke , die OP speziell für fragt W3C Datum Format „vollständige Datum mit Stunden, Minuten, Sekunden und einen Dezimalbruch eines zweiten YYYY-MM-DDThh: mm: ss.sZZZ (zB 1997-07-16T19: 20: 30.45 + 01: 00) " - W3C Datums- und Zeitformate .
Hakre
8

Wie wäre es mit guten alten:

$ date +%Y-%m-%dT%T%z
2015-10-29T14:47:06+0200
Eran Chetzroni
quelle
Wo sind die Zeitzoneninformationen?
Raphael Ahrens
Dies funktioniert sowohl unter Mac als auch unter Linux 'Date'
Eran Chetzroni
1
Wie wäre es mit Millisekunden?
Martin Jambon
6
Kurzer Hinweis: Ohne den RFC zu öffnen, 0200fehlt dem Zeitzonensegment ein Doppelpunkt. Dies kann dazu führen, dass einige Systeme beschädigt werden, die dies erfordern.
Mike Mackintosh
2
@ MikeMackintoshs Anmerkung ist relevant; Die hier gezeigte Ausgabe ist kein legales RFC 3339-Datum. Der Doppelpunkt im Zeitzonensegment ist für RFC 3339 erforderlich. Siehe die Definition time-numoffsetunter tools.ietf.org/html/rfc3339#section-5.6 .
Mark Amery
7

Sie können die Zeit auch einfacher gemäß RFC3339 (ISO8601) formatieren :

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

HINWEIS: Dieses Format wird auch in der Label Schema Convention RC 1.0 verwendet

Daniel Andrei Mincă
quelle
Das ist kein gültiger RFC3339. Erans Antwort von `` `Datum +% Y-% m-% dT% T% z` `` ist korrekt und enthält weniger Zeichen. Wenn Sie in UTC wollen, übergeben Sie das Flag -u, wodurch der Zeitzonen-Offset auf Null gesetzt wird.
briceburg
Mit der -uFlagge ist diese Antwort richtig, oder?
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'

Diese Befehle sind mit Ausnahme der %zKonvertierungsspezifikation POSIX-kompatibel . Es wird jedoch %zweitgehend unterstützt und funktioniert auf die gleiche Weise unter Linux, MacOS, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Solaris, Minix und Haiku. Es funktioniert auch mit den Tools in Busybox, Toybox und sbase (den Systemdienstprogrammen von suckless.org). Da %zder Zeitzonen-Offset im ±HHMMFormat ausgegeben wird, muss die sedPipe einen Doppelpunkt hinzufügen und in ändern ±HH:MM.

HINWEIS: Der dateBefehl des Heirloom-Projekts weist eine inkompatible %zAusgabe auf: Es wird kein +Zeichen gedruckt .

Lassi
quelle