Wie kann ich die Uhrzeit von einer anderen Zeitzone ausgeben lassen?

115

Ich habe einen Server mit der eingestellten Zeitzone UTC. Es schien, als wäre das im Allgemeinen eine gute Übung (bitte korrigieren Sie mich, wenn ich falsch liege).

Auf jeden Fall scpläuft einer der Server, mit denen ich eine Verbindung herstelle, um Dateien zu erstellen, EDTund speichert Dateien, die ich kopieren muss, im Format/path/to/filename/data20120913

Ich habe versucht, rsyncDateien mit so etwas wie find's -mtime -1flag für Dateien zu bearbeiten, die am letzten Tag geändert wurden, aber ich hatte kein Glück.

Es macht mir nichts aus, nur scpdie Datei des aktuellen Tages zu kopieren, aber derzeit gibt es ein 4-Stunden-Fenster, in dem die Ausführung date +%Y%m%dauf jedem Server einen anderen Tag anzeigt, was mich ein wenig stört.

Wenn man dateich durchschaue, sehe ich, dass ich die Zeit als ausgeben lassen kann UTC, aber ich sehe keine Möglichkeit, sie als eine andere Zeitzone auszugebenEDT

Ich nehme an, ich könnte auch so etwas wie die GNUDatumserweiterung verwenden date -d 20100909 +%s, um das Datum in Sekunden aus der Epoche abzurufen, eine manuelle Sekundenberechnung anzuwenden 4 * 60 * 60und das Datum als Datum zu rendern - aber dann, wenn die Sommerzeit einsetzt, ist es noch eine Stunde frei .

Gibt es eine einfachere Möglichkeit, das Datum in einem YYYYMMDDFormat für EDTeinen Server auszugeben, der auf festgelegt ist UTC?

cwd
quelle
EDT ist zumindest unter Linux keine anerkannte Zeitzone. Siehe mein "Sei vorsichtig!" Antwort unten für die ganze hässliche Geschichte. Wenn EDT auf Ihrer Marke von * NIX erkannt wird, sollten Sie dennoch Vorsicht walten lassen und Ihre Zeitzonenzeichenfolge überprüfen.
Mike S

Antworten:

175

Sie können eine Zeitzone für die Dauer der Abfrage festlegen.

TZ=America/New_York date

Beachten Sie das Leerzeichen zwischen der TZEinstellung und dem dateBefehl. In einer Bourne-ähnlichen und einer rcähnlichen Shell wird die TZVariable nur für die Befehlszeile festgelegt. In anderen Schalen ( csh, tcsh, fish), können Sie immer die Verwendung envBefehl statt:

env TZ=America/New_York date

tl; dr

Auf Linux-Systemen. Zeitzonen werden in Dateien im /usr/share/zoneinfoVerzeichnis definiert. Diese Struktur wird oft als "Olson-Datenbank" bezeichnet, um den Gründungsbeitrag zu ehren.

Die Regeln für jede Zeitzone sind als Textdateizeilen definiert, die dann in eine Binärdatei kompiliert werden. Die so kompilierten Zeilen definieren den Zonennamen. einen Daten- und Zeitbereich, für den die Zone gilt; ein Versatz von UTC für die Standardzeit; und die Notation zum Definieren, wie der Übergang von und zur Sommerzeit erfolgt, falls zutreffend.

Beispielsweise enthält das Verzeichnis "Amerika" die erforderlichen Informationen für New York in der oben verwendeten Datei America/New_York.

Beachten Sie, dass die Angabe einer nicht vorhandenen Zone (Dateiname) unbemerkt ignoriert und UTC-Zeiten gemeldet werden. Beispielsweise meldet dies eine falsche Zeit:

TZ="America/New York" date ### WRONG ###

In der Single UNIX-Spezifikation, Version 3, bekannt als SUSv3 oder POSIX-2001, wird darauf hingewiesen, dass aus Gründen der Portabilität die Zeichenfolge, die die Beschreibung der Zeitzone angibt, mit einem Doppelpunkt beginnen sollte. So können wir auch schreiben:

TZ=":America/New_York" date
TZ=":America/Los_Angeles" date

Als alternative Methode zur Angabe von Zeitzonen unter Verwendung eines Pfadnamens zu einer Beschreibungsdatei beschreibt SUSv3 das POSIX-Modell. In diesem Format ist eine Zeichenfolge wie folgt definiert:

std offset [dst[offset][,start-date[/time],end-date[/time]]]

Wo stdist der Name der Standardkomponente und wo dstist die Sommerzeit? Jeder Name besteht aus drei oder mehr Zeichen. Das offsetist positiv für Zeitzonen westlich des Nullmeridians und negativ für jene östlich des Nullmeridians. Der Offset wird zur Ortszeit addiert, um die UTC (früher als GMT bekannt) zu erhalten. Die Felder startund endZeit geben an, wann die Standard- / Tageslichtübergänge auftreten.

In den östlichen USA liegt die Standardzeit beispielsweise 5 Stunden vor UTC, und wir können EST5EDTanstelle von angeben America/New_York. Diese Alternativen werden jedoch insbesondere für Gebiete außerhalb der USA nicht immer anerkannt und sollten vermieden werden.

HP-UX (ein SUSv3-kompatibles UNIX) verwendet Textregeln in /usr/lib/tztabund die POSIX-Namen wie EST5EDT, CST6CDT, MST7MDT, PST8PDT. Die Datei enthält alle historischen Regeln für jede Zeitzone, ähnlich der Olson-Datenbank.

HINWEIS: Sie sollten in der Lage sein , alle der Zeitzonen zu finden , indem Sie das folgende Verzeichnis Inspektion: /usr/share/zoneinfo.

JRFerguson
quelle
wenn ich falsch nicht sicher, aber exportsieht besser aus als envBefehl
insign
@JRFerguson - Wenn eine Zeitzone nicht in der Liste enthalten ist, z. B. Las Vegas oder Nevada, welche Alternativen stehen zur Verfügung, um die Zeit zu validieren?
Motivierter
@Motivated Wenn Ihre Stadt oder Ihr Bundesstaat nicht enthalten ist, wählen Sie eine, die dieselben Zoneninformationen wie Ihre verwendet. Zum Beispiel bin ich in Florida, wo die gleiche Zeitzone wie in New York verwendet wird, sodass meine Maschinen mit der New Yorker Zeit synchronisiert werden.
JRFerguson
1
@JRFerguson - Dies setzt voraus, dass die Person die verschiedenen Zeitzonen kennt und in Ihrem Fall eine Alternative verwenden kann, z. B. New York. Wäre das die einzige Option? Zum Beispiel lebe ich nicht in Europa und kenne die überlappenden Zeitzonen nicht.
Motivierter
1
@Motivated Sie können so etwas wie diese Website verwenden , um andere Punkte in Ihrer Zone zu finden.
JRFerguson
33

Sie können dies tun, indem Sie die TZUmgebungsvariable bearbeiten. Im Folgenden finden Sie die Ortszeit für US / Eastern, die auch für die Sommerzeit geeignet ist:

# all on one line
TZ=":US/Eastern" date +%Y%m%d

Der Zonenname stammt aus den darin enthaltenen Dateien und Verzeichnissen /usr/share/zoneinfo.

James Sneeringer
quelle
17

Achtung! Das Datum gibt die Zeit in Ihrer CURRENT-Zeitzone aus. Wenn Sie eine Zeitzone angeben, wird diese nicht erkannt.

Überprüfen Sie dies heraus:

-bash-4.2$ env TZ=EDT date
Wed Feb 18 19:34:41 EDT 2015
-bash-4.2$ date
Wed Feb 18 19:34:43 UTC 2015

Beachten Sie, dass es keine Zeitzone namens EDT gibt. In der Tat,

-bash-4.2$ find /usr/share/zoneinfo -name "*EDT*"

kehrt zurück

/usr/share/zoneinfo/EST5EDT
/usr/share/zoneinfo/posix/EST5EDT
/usr/share/zoneinfo/right/EST5EDT

Und das funktioniert:

-bash-4.2$ TZ=EST5EDT date
Wed Feb 18 14:36:59 EST 2015
-bash-4.2$ date
Wed Feb 18 19:37:01 UTC 2015

Wenn Ihr Freund jedoch im mystischen Land Gobbledygook lebt und seine Zoneninformationen mit Ihren eigenen übereinstimmen, können Sie die Uhrzeit in der Zone von Gobbledygook als Datum ausgeben lassen Zone ist ihm nicht bekannt:

-bash-4.2$ TZ=Gobbledygook date
Wed Feb 18 19:37:36 Gobbledygook 2015
-bash-4.2$ echo $?
0
Mike S
quelle
YMMV: Auf meiner MacOS / BSD-Box gibt ein fehlerhafter TZString die UTC-Zeit zurück.
Mark Hudson
8
TODAY=$(TZ=":US/Eastern" date)
echo $TODAY
Lin
quelle
6

Der Zeitpunkt Syntax ist obskur und fehleranfällig, was ein Schmerz Kommandozeilenaufruf macht. Ich habe daher ein kleines Skript geschrieben (ich habe es Weltzeit genannt ), das die angegebene (oder aktuelle) Zeit ausgehend von der Basiszeit (Ihrer lokalen) in einigen anderen Zeitzonen und umgekehrt ausgibt.

Hier ist es. Passen Sie es an Ihre Bedürfnisse an, fügen Sie es in Ihren Pfad ein und machen Sie es ausführbar.

#! / bin / sh
#
# Die angegebene (oder aktuelle) Zeit ausgehend von der Basiszeit in anderen Zeitzonen drucken
# und das Gegenteil
#

# Basiszeitzone von / zu der konvertiert werden soll
TZBASE = Europa / Athen

# Zeitzonen, die angezeigt werden sollen
# Weitere Namen finden Sie unter / usr / share / zoneinfo /
TZONES = 'UTC Amerika / Los_Angeles Amerika / New_York Europa / London Europa / Paris'

# Anzeigeformat
FORMAT = '% H:% M (% p)% Z% a% m% b% Y'

if ["$ 1"]; dann
  time = "$ 1"
sonst
  Zeit = `Datum +% T`
fi

# Zeigt die Zeit aus der angegebenen Eingabezeitzone in der angegebenen Ausgabe an
# Zeitzone
Show Time()
{
  TZIN = 1 USD
  TZOUT = $ 2

  TZ = $ TZOUT Datum - Datum = 'TZ = "' $ TZIN '"' "$ Zeit" + "$ Zeit $ TZIN ist $ TZOUT $ FORMAT"
}

für tz in $ TZONES; machen
  showtime $ TZBASE $ tz
getan

Echo

für tz in $ TZONES; machen
  showtime $ tz $ TZBASE
getan

Diomidis Spinellis
quelle
3

Oft haben Sie einen Zeitstempel in der lokalen Zeitzone und müssen ihn in Remote-TZ konvertieren. Es kann gemacht werden mit:

TZ=America/Curacao date -d 'Tue Nov 28 00:07:05 MSK 2016'

wo:

America/Curacao - remote timezone
MSK - local timezone
dimcha
quelle