it-swarm-eu.dev

Jak mohu mít "datum" výstup času z jiného časového pásma?

Mám spuštěný server s časovým pásmem nastaveným na UTC. Vypadalo to, že to byl obecně dobrý postup (prosím, opravte mě, pokud se mýlím).

Každopádně jeden ze serverů, ke kterým se připojuji, běží za účelem scp souborů na EDT a ukládá soubory, které musím zkopírovat ve formátu /path/to/filename/data20120913

Podíval jsem se na pokus o rsync soubory pomocí něco jako nález -mtime -1 Pro soubory upravené za poslední den, ale neměl jsem štěstí.

Nevadilo by mi jen zkopírovat soubor aktuálního dne pomocí scp, ale od této chvíle existuje 4-hodinové okno, kde spuštění date +%Y%m%d Dá jiný den na každém serveru a to trochu mi chybí.

Když se dívám skrz man date Vidím, že mohu mít časový výstup jako UTC, ale nevidím způsob, jak ho mít jako další časové pásmo, jako je EDT

Předpokládám, že bych mohl také použít něco jako GNU rozšíření data date -d 20100909 +%s Pro získání data v sekundách od epochy, použít manuální 4 * 60 * 60 Druhý výpočet a podívat se na vykreslení, které jako datum - ale pak, když do něj zaskočí letní čas, bude stále ještě jedna hodina volna.

Existuje jednodušší způsob, jak vydat datum ve formátu YYYYMMDD pro EDT na serveru nastaveném na UTC?

119
cwd

Můžete nastavit časové pásmo na dobu trvání dotazu, tedy:

TZ=America/New_York date

Všimněte si mezeru mezi nastavením TZ a příkazem date. V Bourne-like a rc- Shell, které nastaví proměnnou TZ pouze pro příkazový řádek. V jiných shellech (csh, tcsh, fish) můžete místo toho vždy použít příkaz env:

env TZ=America/New_York date

tl; dr

Na systémech Linux. časová pásma jsou definována v souborech v adresáři /usr/share/zoneinfo. Tato struktura je často označována jako „Olsonova databáze“ k poctě jejím zakladatelům.

Pravidla pro každé časové pásmo jsou definována jako řádky textového souboru, které jsou pak zkompilovány do binárního souboru. Takto zkompilované řádky definují název zóny; rozsah dat a času, během kterého se zóna použije; offset od UTC pro standardní čas; a notace pro definování toho, jak dochází k přechodu na letní čas a zpět, pokud je to použitelné.

Například adresář „America“ obsahuje požadované informace pro New York v souboru America/New_York, Jak bylo použito výše.

Dejte pozor, aby specifikace neexistující zóny (název souboru) byla bezobslužně ignorována a byly zaznamenány časy UTC. Například to hlásí nesprávný čas:

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

Single UNIX Specification, verze-3, známá jako SUSv3 nebo POSIX-2001, uvádí, že pro přenositelnost by řetězec znaků, který identifikuje popis časového pásma, měl začínat dvojtečkou. Můžeme tedy také napsat:

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

Jako alternativní metoda ke specifikaci časových pásem pomocí cesty k souboru popisu popisuje SUSv3 model POSIX. V tomto formátu je řetězec definován jako:

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

kde std je standardní název komponenty a dst je letní. Každé jméno se skládá ze tří nebo více znaků. offset je pozitivní pro časové pásmo západně od hlavního poledníku a negativní pro ty východně od poledníku. Posun se přidá k místnímu času, aby se získal UTC (dříve známý jako GMT). Časová pole start a end označují, kdy dojde k přechodu na standardní/denní světlo.

Například ve východních Spojených státech je standardní čas o 5 hodin dříve než UTC a místo EST5EDT Můžeme zadat America/New_York. Tyto alternativy však nejsou vždy uznávány, zejména pro zóny mimo Spojené státy, a nejlépe se jim vyhnout.

HP-UX (UNIX kompatibilní s SUSv3) používá textová pravidla v /usr/lib/tztab A názvy POSIX jako EST5EDT, CST6CDT, MST7MDT, PST8PDT. Soubor obsahuje všechna historická pravidla pro každé časové pásmo, podobné databázi Olson.

POZNÁMKA: Měli byste být schopni najít všechna časová pásma prohlédnutím následujícího adresáře: /usr/share/zoneinfo.

186
JRFerguson

To lze provést manipulací s proměnnou prostředí TZ. Následující vám poskytne místní čas pro USA/východní, který bude také dostatečně chytrý na to, aby zvládl DST, když se to bude pohybovat kolem:

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

Název zóny pochází ze souborů a adresářů uvnitř /usr/share/zoneinfo.

33
James Sneeringer

Buď opatrný! Datum šťastně vyplivne čas ve vašem aktuálním časovém pásmu, pokud mu dáte časové pásmo, které nerozpozná.

Koukni na tohle:

-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

Všimněte si, že neexistuje žádné časové pásmo zvané EDT. Ve skutečnosti,

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

se vrací

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

A to funguje:

-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

Pokud však váš přítel žije v mystické zemi Gobbledygook a její informace o zóně se shodují s vaší vlastní, můžete mít datum výstupu času v zóně Gobbledygook a budete rádi, když tak učiníte s nary výstupní hodnotou, abyste věděli, že zóna není známa:

-bash-4.2$ TZ=Gobbledygook date
Wed Feb 18 19:37:36 Gobbledygook 2015
-bash-4.2$ echo $?
0
20
Mike S
TODAY=$(TZ=":US/Eastern" date)
echo $TODAY
9
Lin

Syntaxe date je tajemná a náchylná k chybám, což způsobuje bolest vyvolání příkazového řádku. Proto jsem napsal malý skript (pojmenoval jsem ho worldtime), který vytiskne určený (nebo aktuální) čas ze zome základny (vašeho místního) v některých dalších časových pásmech a obráceně.

Tady to je. Upravte ji tak, aby vyhovovala vašim potřebám, vložte ji do cesty a zajistěte, aby byla spustitelná.

 #!/bin/sh 
 # 
 # Vytiskněte určený (nebo aktuální) čas od základního času v jiných časových pásmech 
 # a obráceně 
 # 
 
 # Základní časové pásmo, ze kterého/do kterého chcete převést 
 TZBASE = Evropa/Atény 
 
 # Časová pásma k zobrazení 
 # Viz/usr/share/zoneinfo/pro více jmen 
 TZONES = 'UTC America/Los_Angeles America/New_York Europe/London Europe/Paris' 
 
 # Formát zobrazení 
 FORMÁT = '% H:% M (% p)% Z% a% m% b% Y' 
 
 Pokud ["$ 1"]; pak 
 time = "$ 1" 
 else 
 time = `date +% T` 
 fi 
 
 # Zobrazit čas ze zadaného časového pásma v zadaném výstupu 
 # časové pásmo 
 showtime () 
 {
 TZIN = $ 1 
 TZOUT = $ 2 
 
 TZ = $ TZOUT datum - datum = 'TZ = "' $ TZIN '"' "$ time" + "$ time $ TZIN je $ TZOUT $ FORMAT" 
} 
 
 za tz v $ TZONES; do 
 showtime $ TZBASE $ tz 
 udělal 
 
 echo 
 
 pro tz v $ TZONES; do 
 showtime $ tz $ TZBASE 
 hotovo 
 
7

Často máte časové razítko v místním časovém pásmu a musíte je převést na vzdálené tz. To lze provést pomocí:

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

kde:

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