ubuntuusers.de

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:

Wiki/Icons/terminal.png

Mit dem Programm date lässt sich die Systemzeit (Software-Uhr) anzeigen und manipulieren. Dabei gibt es im Wesentlichen drei Anwendungsgebiete:

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.

Diese Revision wurde am 10. April 2024 14:46 von wxpte erstellt.