date
Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:
Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.
Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:
⚓︎ Spracheinstellungen , optional (Beeinflusst
date
-Ausgabeformat)
Mit dem Programm date lässt sich die Systemzeit (Software-Uhr) anzeigen und manipulieren. Dabei gibt es im Wesentlichen drei Anwendungsgebiete:
Verwendung zur Programmführung in Shell-Skripten
Einstellen von Datum und Uhrzeit, sofern diese nicht über einen Zeitserver synchronisiert werden
Installation¶
Das Programm date ist im essentiellen Paket
coreutils
von Ubuntu enthalten. Eine Installation ist daher nicht notwendig.
Syntax¶
Je nach Verwendung gilt für den Aufruf von date die folgende Syntax:
Anzeige und Verwendung in Skripten:
date [OPTION]… [+FORMAT]
Einstellen von Datum und Uhrzeit (hierfür werden root-Rechte benötigt):
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
Optionen¶
Die folgenden Optionen sind für date verfügbar:
Überblick¶
Übersicht der Optionen | |
Optionen | Bedeutung |
-d oder--date=ZEICHENKETTE | Den in ZEICHENKETTE angegebenen Zeitpunkt – abweichend von der aktuellen Systemzeit – anzeigen. Näheres dazu siehe unten. |
--debug | Die Auswertung des angegebenen Zeitpunkts wird detailliert angezeigt. Wird date nur mit dieser Option aufgerufen, wird der voreingestellte Formatcode angezeigt. |
-f oder--file=DATUMSDATEI | Statt ZEICHENKETTE (Option --date ) kann DATUMSDATEI zeilenweise ausgelesen und ausgegeben werden. |
-I[FMT] oder--iso-8601[=FMT] | Der Zeitpunkt wird im ISO_8601-Format angezeigt. Mit FMT kann die Genauigkeit festgelegt werden: date = nur Datum (Voreinstellung), hours = Stunden, minutes = Minuten, seconds = Sekunden und ns = Nanosekunden.Im Gegensatz zum voreingestellten Format (siehe oben, Option --debug ) lässt sich dieses Format durch die Option -d auswerten. |
--resolution | verfügbare Auflösung für Zeitstempel anzeigen. |
-R oder--rfc-email | Datum und Zeit werden in dem Format, wie es in RFC 5322 für den Header von E-Mails normiert ist, angezeigt. Auch dieses Format lässt sich durch die Option -d auswerten. |
--rfc-3339=FMT | Der Zeitpunkt wird im RFC-3339-Format angezeigt. Dieses weicht geringfügig vom ISO-8601-Format (siehe oben, Option -I ) ab. FMT muss hier zwingend angegeben werden, eine Voreinstellung gibt es nicht. Zudem sind bei dieser Option nur die Genauigkeiten date , seconds und ns verfügbar.Auch dieses Format lässt sich durch die Option -d auswerten. |
-r oder--reference=DATEI | Der Zeitpunkt der letzten Änderung der angegebenen Datei wird angezeigt. Im Gegensatz zur Ausgabe über stat -c %y lässt sich das Ausgabeformat individuell gestalten. |
-s oder--set=ZEICHENKETTE | Die Software-Uhr wird auf den angegebenen Zeitpunkt gesetzt (hierfür werden root-Rechte benötigt). Abweichend von der oben beschriebenen Syntax kann mit dieser Option auch jedes andere mit der Option -d auswertbare Format verwendet werden. |
-u oder--utc oder--universal | Entsprechend der vorkonfigurierten Zeitzone wird der angezeigte Zeitpunkt in die Koordinierte Weltzeit umgerechnet. Beim Einstellen der Software-Uhr wird die Koordinierte Weltzeit eingetragen und für die Anzeige entsprechend der vorkonfigurierten Zeitzone umgerechnet. |
--help | Anzeige der Hilfe (Kurzübersicht ) 🇬🇧. |
--version | Anzeige der Versionsinformationen. |
Verschiedene Zeitangaben¶
Wie bereits in der Tabelle beschrieben, kann mit der Option -d
ein Zeitpunkt angezeigt werden, welcher sich von der in der Softare-Uhr aktuell eingestellten Zeit unterscheidet. Der anzuzeigende Zeitpunkt kann auf zwei verschiedene Arten definiert werden.
Absolute Zeitangaben¶
Eine absolute Zeitangabe kann mit beliebiger Genauigkeit definiert werden. Beim Format ist jedoch zu berücksichtigen, dass ausschließlich die Standardformate der amerikanischen locale sowie Formate internationaler Normen akzeptiert werden. Dies sind insbesondere:
das Format nach ISO 8601
das Format nach RFC 5322
das Format nach RFC 3339
das Format der amerikanischen locale (numerisch und alphanumerisch)
die Angabe mit Hilfe der Unixzeit
sowie Teilausschnitte dieser Formate. Beispielsweise werden die folgenden Angaben akzeptiert:
date -d'Thu, 04 Jul 2024 14:30' '+%d. %b %Y %R'
04. Jul 2024 14:30
Für Wochentags- oder Monatsnamen können die gebräuchlichen englischen Kürzel oder der ausgeschriebene englische Name verwendet werden. Bei der Tagesangabe sind in der alphanumerischen Form keine Zusätze wie z. B. ein Punkt erlaubt. Nachfolgend eine Angabe mit dem ISO-8601-Format in der Genauigkeit minutes
:
date -d'2024-10-03T11:15+02:00' '+%d. %b %Y %R'
03. Okt 2024 11:15
Dass auch Teilausschnitte zulässig sind, zeigt die folgende Angabe unter teilweiser Verwendung des Formats RFC 3339:
date -d'2024-10-03 11:15' '+%d. %b %Y %R'
03. Okt 2024 11:15
Das amerikanische numerische Format kann sehr minimalistisch verwendet werden:
date -d'7/4/24 2:30 pm' '+%d. %b %Y %R'
04. Jul 2024 14:30
Die Verwendung einer führenden Null oder einer vierstelligen Jahreszahl ist hier nicht erforderlich, und für das Zeitformat ist sowohl das 24-Stunden- als auch das 12-Stunden-Format zulässig. Der Nachteil ist jedoch, dass die Reihung des Datumsformats (Monat/Tag/Jahr
) den deutschen Gewohnheiten widerspricht und daher leicht verwechselt werden kann. Zudem sollte bei der Verwendung der zweistelligen Jahreszahl beachtet werden, dass zukünftige Angaben nur bis ins Jahr 2068 reichen, und das System danach auf das Jahr 1969 umschaltet.
Abschließend soll noch gezeigt werden, wie man den Zeitpunkt mit Hilfe der Unixzeit angibt:
date -d'@1720096200' '+%d. %b %Y %R'
04. Jul 2024 14:30
Die Bedeutung des Ausgabeformats (+%d. %b %Y %R
) wird unten im Abschnitt "Formatangaben" näher erläutert.
Relative Zeitangaben¶
Neben den absoluten Zeitangaben sind auch relativ auf die aktuelle Systemzeit bezogene Zeitangaben möglich. Im einfachsten Fall ist dies:
date -d'yesterday'
beziehungsweise:
date -d'tomorrow'
Für die Einheiten second, minute, hour, day, week, month
und year
(im Folgenden [unit]
genannt) kann die Zeitangabe, bezogen auf den aktuellen Zeitpunkt, eine beliebige Anzahl von [unit]
in die Zukunft oder in die Vergangenheit gesetzt werden:
date -d'1 [unit]'
gibt einen Zeitpunkt aus, welcher eine Einheit in der Zukunft liegt,
date -d'5 [unit]'
gibt einen Zeitpunkt aus, welcher fünf Einheiten in der Zukunft liegt. Dabei kann [unit]
auch in der Pluralform benannt werden (z. B. days
), dies ist aber nicht erforderlich.
date -d'-2 [unit]'
gibt einen Zeitpunkt an, welcher die angegebene Anzahl von Einheiten (in diesem Fall zwei) in der Vergangenheit liegt. Statt einer Zahl mit negativem Vorzeichen kann auch die folgende Form gewählt werden:
date -d'2 [unit] ago'
Wird die Einheit second
gewählt, so können auch Nachkommastellen berechnet werden:
date -d'0.5 second'
Sofern die Differenz genau eine Einheit betragen soll, sind auch die folgenden Formen zulässig:
date -d'next [unit]'
date -d'last [unit]'
Achtung!
Normalerweise berücksichtigt die Einheit month
, dass ein Monat zwischen 28 und 31 Tage haben kann. Dennoch kommt es an den Grenzen eines Monats zu Problemen zwischen mathematisch korrekter Berechnung und praktischer Anwendung. Nachfolgend ein Beispiel hierfür:
date -d"$(date -d'2024-10-31 11:15' '+%F %R') next month" +%B
Dezember
Rein auf den Monat bezogen, ist auch am 31.10. noch der November der nächste Monat. Um hier eine korrekte Aussage zu treffen, ist die folgende Konstruktion hilfreich:
date -d"$(date +%Y-%m-01) next month"
In diesem Fall wird der 1. Tag des aktuellen Monats, 0:00 Uhr als Basis genommen.
Die Regeln für die relative Zeitangabe mit Hilfe eines Wochentags (im Folgenden [weekday]
genannt) unterscheiden sich ein wenig von denen der übrigen Einheiten. Während bei den anderen Einheiten die volle Einheit, multipliziert mit dem Faktor, addiert oder subtrahiert wird, wird bei der Angabe des Wochentags auf den Beginn dieses Tages gesetzt:
date '+%a, %d. %b %Y %R'; date -d'next saturday' '+%a, %d. %b %Y %R'
Fr, 08. Mär 2024 20:17 Sa, 09. Mär 2024 00:00
Möglich ist hier auch die Angabe:
date -d'3 [weekday]'
In diesem Fall werden zu dem Abstand zum aktuellen Zeitpunkt noch zwei Wochen hinzugefügt. Dagegen ist eine entsprechende Angabe in Richtung Vergangenheit nicht definiert. Lediglich die Angabe:
date -d'last [weekday]'
ist erlaubt.
Eine entsprechende Möglichkeit mit Hilfe von Monatsnamen gibt es dagegen nicht.
Formatangaben¶
Formatangaben werden mit dem Zeichen +
zu Beginn der Zeichenkette als Ausgabeformat gekennzeichnet. Ähnlich, wie beim Befehl echo können hiermit beliebige Zeichenketten ausgegeben werden (enthält eine Zeichenkette Leerzeichen, muss sie zusätzlich gequotet werden). Damit aber in Zusammenhang mit dem Befehl date
sinnvolle Ausgaben möglich sind, wurden für die Formatangaben eine Reihe von Platzhaltern definiert, welche die verschiedenen Datums- und Zeitformate (einschließlich Zeitzonenkennungen) repräsentieren. Nachfolgend sind die gebräuchlichsten Platzhalter gelistet.
Die wichtigsten Platzhalter | |
Platzhalter | Beschreibung |
%a | Das Kürzel des Wochentags wird in der jeweiligen Locale angezeigt. In der deutschen Locale sind dies: Mo, Di, Mi, Do, Fr, Sa und So. |
%A | Der Name des Wochentags wird gemäß der jeweiligen Locale vollständig geschrieben. |
%b oder %h | Das Kürzel des Monatsnamens wird in der jeweiligen Locale angezeigt. In der deutschen Locale sind dies: Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov und Dez. Benötigt man das Monatskürzel zur weiteren Auswertung mit der Option -d , so kann man die Ausgabe mit LC_TIME=en.US date +%b erzeugen. Dies gilt auch für alle anderen Platzhalter mit Bezug auf die Locale. |
%B | Der Monatsname wird gemäß der jeweiligen Locale vollständig ausgeschrieben. |
%c | Eine Repräsentation von Datum und Zeit in der jeweiligen Locale. In der deutschen Locale ist dies z. B. "Do 03 Okt 2024 11:15:00 CEST" Sie unterscheidet sich nur geringfügig von der Ausgabe ohne Formatangabe: "Do 3. Okt 11:15:00 CEST 2024" |
%d | Der Tag des Monats wird zweistellig (01 bis 31) angezeigt. Weitere Zusätze (wie z. B. ein Punkt) müssen explizit angegeben werden. Beispiel: "+%d. %b %Y" . Wegen der Leerzeichen muss im Beispielsfall zwingend gequotet werden. |
%D | Das amerikanische Datumsformat, durchgehend zweistellig dargestellt (z. B. 07/04/24 ). |
%e oder %_d | Einstellige Tage des Monats werden statt mit einer führenden Null mit einem Leerzeichen aufgefüllt. |
%F | Entspricht weitgehend der Anzeige mit der Option -I , Genauigkeit date (z. B. 2024-10-03 ), enthält jedoch noch eine Erweiterung: weit in der Zukunft liegende Zeitpunkte ab fünfstelliger Jahreszahl enthalten ein vorangestelltes + . |
%H | Die Stunde wird im 24-Stunden-Format (00 bis 23) angezeigt. |
%I | Die Stunde wird im 12-Stunden-Format (01 bis 12) angezeigt. |
%j | Der Tag des Jahres wird durchgängig dreistellig angezeigt (001 bis 366). |
%k oder %_H | Bei Angaben im 24-Stunden-Format wird statt einer führenden Null ein Leerzeichen verwendet. |
%l oder %_I | Bei Angaben im 12-Stunden-Format wird statt einer führenden Null ein Leerzeichen verwendet. |
%m | Der Monat wird numerisch (01 bis 12) angezeigt. Für diesen Platzhalter gilt das zu %d geschriebene entsprechend. |
%M | Die Minute wird angezeigt (00 bis 59). |
%N | Sekundenbruchteile werden als Nanosekunden (neunstellige Ganzzahl, ggf. mit führenden Nullen) angezeigt. |
%q | Das Quartal des Jahres (1 bis 4) wird angezeigt. |
%r | Die sekundengenaue Zeit wird im 12-Stunden-Format der Locale angezeigt. Trenner zwischen den Einheiten ist : . |
%R | Die minutengenaue Zeit wird im 24-Stunden-Format angezeigt. Trenner ist hier ebenfalls : . |
%s | Der Zeitpunkt wird als Unixzeit angezeigt. Für Zeitpunkte vor dem 01.01.1970 00:00 Uhr UTC erhält die Angabe ein negatives Vorzeichen. |
%S | Die Sekunde wird angezeigt (00 bis 60). |
%T | Die sekundengenaue Zeit wird im 24-Stunden-Format angezeigt. Trenner zwischen den Einheiten ist : . |
%u | Der Tag der Woche wird in numerischer Schreibweise von 1 (Montag) bis 7 (Sonntag) angezeigt. |
%V | Die Kalenderwoche wird im ISO_8601-Format angezeigt (01 bis 53, Montag ist der erste Tag der Woche). |
%x | Die Datumsrepräsentation der Locale wird angezeigt (z. B. 03.10.2024). |
%X | Die Zeitrepräsentation der Locale wird angezeigt (z. B. 14:30:00). |
%y | Die letzten zwei Ziffern des Jahres werden angezeigt (00 bis 99). |
%Y | Die gesamte Jahreszahl wird angezeigt. Im Gegensatz zum Platzhalter %F wird kein + vorangestellt, sofern die zukünftige Jahreszahl mehr als vier Stellen hat. |
%:z | Die Zeitzone wird in der üblichen numerischen Form (z. B. +01:00) angezeigt. |
%Z | Die Zeitzone wird in der üblichen alphabetischen Form (z. B. CET) angezeigt. |
Die vollständige Liste der Platzhalter sowie der Schalter, mit denen die Platzhalter modifiziert werden können, ist in der Manpage 🇩🇪 beschrieben.
Beispiele¶
Wenn man im privaten Bereich lediglich eine überschaubare Anzahl an Skripten pflegt, dann mag es etwas zu aufwändig erscheinen, diese über eine vollwertige Versionierung mit Hilfe von git zu verwalten. Mit dem folgenden Skript, welches verschiedene Möglichkeiten des Befehls date
veranschaulicht, können Skriptdateien vor der Überarbeitung in einem Archiv abgelegt werden:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/bin/bash sichern=$HOME/Skriptarchiv if [ $# -eq 0 ]; then echo; echo "Verwendung: $0 'Dateiname1' 'Dateiname2' ... 'Dateiname9'"; echo; exit fi for dn in "$@"; do if [ ! -f "$dn" ]; then echo "Wurde die Datei $dn gequotet?"; continue fi if grep -Fq '.' <<< $dn; then # Bei Dateinamen, die mindestens einen Punkt enthalten cp -p "$dn" "$sichern/${dn%.*}_$(date +%F_%H%M%S).${dn##*.}" # Füge das Datum vor dem letzten Punkt ein else cp -p "$dn" "$sichern/${dn}_$(date +%F_%H%M%S)" # Setze das Datum ans Ende der Datei fi echo "Die Datei $dn $(date '+wurde am %x um %X Uhr gesichert.')" >> $sichern/Sicherheitskopien.log done |
Abwandlung: Um die Datei Sicherheitskopien.log auch mit dem date
-Befehl auswerten zu können, soll das Format der amerikanischen Locale verwendet werden. Aus persönlichen Vorlieben möchte man außerdem das 12-Stunden-Format verwenden. Dann muss die Zeile 15 wie folgt geändert werden:
1 | echo "Die Datei $dn $(LC_TIME=en.US date '+wurde am; %d %B %Y %I:%M %P; gesichert.')" >> $sichern/Sicherheitskopien.log |
Die beiden Semikola in der Ausgabe helfen, die Zeitangabe (z. B. mit cut) zu isolieren.
Im folgenden Beispiel wird die Anzahl der Tage zwischen zwei Terminen ermittelt:
idpd=$(date -d'07/04/24' +%-j) tde=$(date -d'2024-10-03' +%-j) echo $(( $tde - $idpd ))
91
Mit dem nächsten Skript soll gezeigt werden, wie das Ausgabeformat "Unixzeit" sinnvoll genutzt werden kann. Dabei wird nur eine Zeit (ohne Datum) abgefragt und der angegebene Zeitpunkt in ein für timer units lesbares Format umgewandelt. Anschließend wird der Start einer Anwendung in eine ad-hoc timer unit eingetragen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/bin/bash if [ -z "$1" ]; then # Die gewünschte Zeit kann abgefragt oder ... read -p "Wann soll die gewünschte Aktion beginnen (hh:mm)? - " startzeit else startzeit=$1 # ... als Parameter eingegeben werden. fi tuzeit=$(date -d"$startzeit" '+%F %R') # Umwandlung in ein für timer unit lesbares Format if [ $(date -d"$tuzeit" +%s) -le $(date +%s) ]; then # Prüfung, ob der Zeitpunkt in der Vergangenheit oder Gegenwart liegt # Die folgende Zeile enthält eine Kombination aus absoluter (Variable) und relativer Zeitangabe: tuzeit="$(date -d"$tuzeit tomorrow" '+%F %R')" # Verschiebung des Zeitpunkts um einen Tag. fi # Der Zeitpunkt der Ausführung sollte innerhalb einer üblichen Session (8 Stunden) liegen: if [ $(( $(date -d"$tuzeit" +%s) - $(date +%s) )) -gt 28800 ]; then echo; echo 'Die eingegebene Zeit ist nicht sinnvoll. Bitte prüfen.' exit fi # Der angegebene Zeitpunkt wird in eine ad-hoc timer-unit eingetragen: systemd-run --user --on-calendar="$tuzeit" /pfad/zur/zeitgesteuerten/Anwendung echo; echo "Der Start der Anwendung wurde für den $(date -d"$tuzeit" '+%x %X') eingetragen." |
Um dieses Skript auszuprobieren, muss die Aktion, die über die timer unit ausgeführt werden soll, angepasst werden (z. B. touch ~/testdatei
).
Wer seine Projekte im Terminal hauptsächlich nach Kalenderwochen plant, könnte sich den Prompt wie folgt einrichten:
PS1='\n$(date +%V.) KW, $(date +%A)\n\w\$'
Szenario: Mit einer täglichen Routine wird geprüft, ob auf einem Webserver neue Dateien zum Download hinterlegt sind, und diese ggf. heruntergeladen. Dieser Vorgang wird für ein ganzes Jahr protokolliert. Falls der Vorgang aus technischen Gründen scheitert, fehlt der Eintrag in dieser Protokolldatei, welche etwa wie folgt aussieht:
Protokoll vom 2023-01-01 Es wurden 11 Dateien heruntergeladen. Protokoll vom 2023-01-02 Keine neuen Dateien verfügbar. Protokoll vom 2023-01-03 Es wurden 2 Dateien heruntergeladen. ... Protokoll vom 2023-12-30 Es wurden 1 Dateien heruntergeladen. Protokoll vom 2023-12-31 Es wurden 3 Dateien heruntergeladen.
Nach Ende des Jahres soll mit dem folgenden Skript geprüft werden, ob in dem Jahr Lücken aufgetreten sind:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/bin/bash read -p 'Bitte die zu prüfende Datei angeben: ' datei read -p 'Bitte das Jahr der zu prüfenden Datei eingeben: ' jahr echo '_______________________________________' anfang=$(date -d"$jahr-01-01 12:00" +%s) ende=$(date -d"$jahr-12-31 12:00" +%s) for ((d=$anfang;d<=$ende;d+=86400)); do suche=$(date -d"@$d" +%F) if ! grep -Fq "$suche" $datei; then echo "Am $suche wurde kein Downloadversuch unternommen." fi done |
Erläuterung: Die Variablen anfang
und ende
wurden auf 12:00 Uhr gesetzt, um genügend Puffer für die Umstellungen zwischen Normal- und Sommerzeit zu haben. - Zwar ist dieses Beispiel ein wenig praxisfremd; es ist nur eine Anregung, wie man mit Hilfe einer for-Schleife und dem Befehl date
eine solche Prüfung durchführen könnte.
Links¶
Shell/Befehlsübersicht Übersicht über verschiedene Shell-Befehle