[[Vorlage(Getestet, general)]] {{{#!vorlage Wissen [:Terminal: Ein Terminal öffnen] [:mit Root-Rechten arbeiten:] [:Spracheinstellungen:], optional (Beeinflusst `date`-Ausgabeformat) }}} [[Inhaltsverzeichnis(2)]] [[Bild(Wiki/Icons/terminal.png, 48)]] 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/Bash-Skripting-Guide_für_Anfänger:Shell-Skripten] * Gestaltung des [:Bash/Prompt:Prompts] auf der [:Shell:] * Einstellen von Datum und Uhrzeit, sofern diese nicht über einen [wikipedia: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: {{{#!vorlage Befehl date [OPTION]… [+FORMAT] }}} * Einstellen von Datum und Uhrzeit (hierfür werden root-Rechte benötigt): {{{#!vorlage Befehl date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]] }}} = Optionen = Die folgenden Optionen sind für date verfügbar: == Überblick == {{{#!vorlage Tabelle <-2 tablestyle="width: 97%;" rowclass="titel"> Übersicht der Optionen +++ Optionen Bedeutung +++ `-d` oder[[BR]]`--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[[BR]]`--file=DATUMSDATEI` Statt `ZEICHENKETTE` (Option `--date`) kann `DATUMSDATEI` zeilenweise ausgelesen und ausgegeben werden. +++ `-I[FMT]` oder[[BR]]`--iso-8601[=FMT]` Der Zeitpunkt wird im [wikipedia:ISO_8601:]-Format angezeigt. Mit `FMT` kann die Genauigkeit festgelegt werden: `date` = nur Datum (Voreinstellung), `hours` = Stunden, `minutes` = Minuten, `seconds` = Sekunden und `ns` = Nanosekunden.[[BR]]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[[BR]]`--rfc-email` Datum und Zeit werden in dem Format, wie es in RFC 5322 für den [wikipedia:Header_(E-Mail):Header] von E-Mails normiert ist, angezeigt.[[BR]]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.[[BR]]Auch dieses Format lässt sich durch die Option `-d` auswerten. +++ `-r` oder[[BR]]`--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[[BR]]`--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[[BR]]`--utc` oder[[BR]]`--universal` Entsprechend der vorkonfigurierten Zeitzone wird der angezeigte Zeitpunkt in die [wikipedia:Koordinierte_Weltzeit: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 ) {en}. +++ `--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 [wikipedia:Unixzeit:] sowie Teilausschnitte dieser Formate. Beispielsweise werden die folgenden Angaben akzeptiert: {{{#!vorlage Befehl 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`: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl date -d'yesterday' }}} beziehungsweise: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl date -d'1 [unit]' }}} gibt einen Zeitpunkt aus, welcher eine Einheit in der Zukunft liegt, {{{#!vorlage Befehl 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. {{{#!vorlage Befehl 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: {{{#!vorlage Befehl date -d'2 [unit] ago' }}} Wird die Einheit `second` gewählt, so können auch Nachkommastellen berechnet werden: {{{#!vorlage Befehl date -d'0.5 second' }}} Sofern die Differenz genau eine Einheit betragen soll, sind auch die folgenden Formen zulässig: {{{#!vorlage Befehl date -d'next [unit]' }}} {{{#!vorlage Befehl date -d'last [unit]' }}} {{{#!vorlage Warnung 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: }}} {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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. {{{#!vorlage Tabelle <-2 tablestyle="width: 97%;" rowclass="titel"> 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.[[BR]]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 [wikipedia: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 [wikipedia: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 [man_de:date:Manpage] {de} 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: {{{#!code bash #!/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: {{{#!code bash 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: {{{#!vorlage befehl 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 [:systemd/Timer_Units/#at-Ersatz:timer units] lesbares Format umgewandelt. Anschließend wird der Start einer Anwendung in eine ad-hoc timer unit eingetragen: {{{#!code bash #!/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: {{{#!code bash #!/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} Übersicht über verschiedene Shell-Befehle * [:Shell/Bash-Skripting-Guide_für_Anfänger:Bash-Skripting-Guide für Anfänger] ## Nicht auf diesen Artikel zutreffenden Kategorien bitte löschen! ##tag: Internet, System, Shell, Übersicht, Einsteiger, Programmierung