Come posso avere `data` in uscita l'ora da un fuso orario diverso?


115

Ho un server in esecuzione con il fuso orario impostato su UTC. Sembrava che fosse generalmente una buona pratica (per favore correggimi se sbaglio).

Ad ogni modo, uno dei server a cui mi connetto, per i scpfile, è in esecuzione EDTe memorizza i file che devo copiare nel formato/path/to/filename/data20120913

Ho cercato di provare i rsyncfile usando qualcosa come -mtime -1flag di find per i file modificati nell'ultimo giorno, ma non ho avuto fortuna.

Non mi dispiace solo usare scpper copiare il file del giorno corrente, ma al momento c'è una finestra di 4 ore in cui l'esecuzione date +%Y%m%ddarà un giorno diverso su ciascun server e questo mi dà un po 'di bug.

Guardando attraverso man datevedo che posso avere l'output di tempo come UTC, ma non vedo un modo per farlo emettere come un altro fuso orario comeEDT

Suppongo che potrei anche usare qualcosa di simile GNUall'estensione della data date -d 20100909 +%sper ottenere la data in secondi dall'epoca, applicare un 4 * 60 * 60secondo calcolo manuale e vedere come renderlo come una data - ma poi quando l'ora legale inizia, sarà ancora un'ora di pausa .

Esiste un modo più semplice per generare la data in un YYYYMMDDformato EDTsu un server impostato su UTC?


EDT non è un fuso orario riconosciuto, almeno in Linux. Vedi il mio "Stai attento!" rispondi di seguito per tutta la brutta storia. Se EDT è riconosciuto sulla tua marca di * NIX, devi comunque prestare attenzione e ricontrollare la stringa del fuso orario.
Mike S,

Risposte:


175

È possibile impostare un fuso orario per la durata della query, quindi:

TZ=America/New_York date

Nota lo spazio tra l' TZimpostazione e il datecomando. Nella rcshell simile a Bourne e similare , imposta la TZvariabile solo per la riga di comando. In altre shell ( csh, tcsh, fish), si può sempre utilizzare il envcomando:

env TZ=America/New_York date

tl; dr

Su sistemi Linux. i fusi orari sono definiti nei file nella /usr/share/zoneinfodirectory. Questa struttura viene spesso definita "database Olson" per onorare il suo collaboratore fondatore.

Le regole per ciascun fuso orario sono definite come righe di file di testo che vengono quindi compilate in un file binario. Le linee così compilate, definiscono il nome della zona; un intervallo di dati e tempi durante i quali si applica la zona; un offset da UTC per l'ora standard; e la notazione per definire come avviene la transizione da e verso l'ora legale, se applicabile.

Ad esempio, la directory "America" ​​contiene le informazioni necessarie per New York nel file America/New_Yorkutilizzato in precedenza.

Attenzione che la specifica di una zona inesistente (nome file) viene silenziosamente ignorata e vengono riportati i tempi UTC. Ad esempio, questo segnala un orario errato:

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

La specifica UNIX singola, versione 3, nota come SUSv3 o POSIX-2001, osserva che per la portabilità, la stringa di caratteri che identifica la descrizione del fuso orario dovrebbe iniziare con un carattere due punti. Quindi, possiamo anche scrivere:

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

Come metodo alternativo alla specifica dei fusi orari utilizzando un percorso per un file di descrizione, SUSv3 descrive il modello POSIX. In questo formato, una stringa è definita come:

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

dove stdè il nome del componente standard ed dstè quello dell'ora legale. Ogni nome è composto da tre o più caratteri. Il offsetè positivo per i fusi orari ad ovest del primo meridiano e negativo per quelle ad est del meridiano. L'offset viene aggiunto all'ora locale per ottenere UTC (precedentemente noto come GMT). I campi starte endora indicano quando si verificano le transizioni di luce diurna / standard.

Ad esempio, negli Stati Uniti orientali, l'ora standard è 5 ore prima dell'ora UTC e possiamo specificare EST5EDTal posto di America/New_York. Queste alternative non sono sempre riconosciute, tuttavia, soprattutto per le zone al di fuori degli Stati Uniti e sono meglio evitate.

HP-UX (un UNIX conforme a SUSv3) utilizza regole testuali /usr/lib/tztabe nomi POSIX come EST5EDT, CST6CDT, MST7MDT, PST8PDT. Il file include tutte le regole storiche per ciascun fuso orario, simile al database Olson.

NOTA: Si dovrebbe essere in grado di trovare tutti i fusi orari ispezionando la directory seguente: /usr/share/zoneinfo.


non sono sicuro se sbaglio, ma exportsembra migliore del envcomando
insegni il

@JRFerguson - Se un fuso orario non è incluso nell'elenco, ad esempio Las Vegas o Nevada, quali sono le alternative per convalidare l'ora?
Motivato il

@Motivated Se la tua città o stato non è incluso, scegline uno che utilizza le stesse informazioni sulla tua zona. Ad esempio, sono in Florida, che utilizza lo stesso fuso orario di New York, quindi le mie macchine si sincronizzano con l'ora di New York.
JRFerguson,

1
@JRFerguson - Ciò presuppone che la persona sia a conoscenza dei vari fusi orari e sia in grado di utilizzare un'alternativa, ad esempio New York, nel tuo caso. Sarebbe l'unica opzione? Ad esempio, non vivo in Europa e non conosco i fusi orari sovrapposti.
Motivato il

1
@Motivated Puoi usare qualcosa come questo sito per aiutarti a trovare altri punti nella tua zona.
JRFerguson,

33

Puoi farlo manipolando la TZvariabile d'ambiente. Di seguito ti forniremo l'ora locale per gli Stati Uniti / Est, che sarà anche abbastanza intelligente da gestire l'ora legale quando si sposta:

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

Il nome della zona deriva dai file e dalle directory all'interno /usr/share/zoneinfo.


17

Stai attento! La data sputerà felicemente l'ora nel tuo fuso orario CORRENTE, se gli dai un fuso orario che non riconosce.

Controllalo:

-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

Si noti che non esiste un fuso orario chiamato EDT. Infatti,

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

ritorna

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

E questo funziona:

-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

Tuttavia, se il tuo amico vive nella terra mistica di Gobbledygook e le informazioni sulla sua zona coincidono con la tua, puoi avere la data in uscita l'ora nella zona di Gobbledygook e sarà felice di farlo con un valore di uscita per farti sapere che il la zona non è nota:

-bash-4.2$ TZ=Gobbledygook date
Wed Feb 18 19:37:36 Gobbledygook 2015
-bash-4.2$ echo $?
0

YMMV: sulla mia scatola MacOS / BSD, la TZstringa non valida restituisce l'ora UTC.
Mark Hudson,

8
TODAY=$(TZ=":US/Eastern" date)
echo $TODAY

6

La sintassi della data è arcana e soggetta a errori, il che rende dolorosa l'invocazione da riga di comando. Ho quindi scritto una piccola sceneggiatura (l'ho chiamata worldtime ), che stamperà l'ora specificata (o corrente) dal fuso orario di base (il tuo locale) in alcuni altri fusi orari e viceversa.

Ecco qui. Adattalo in base alle tue esigenze, mettilo nel tuo percorso e rendilo eseguibile.

#! / Bin / sh
#
# Stampa l'ora specificata (o corrente) dall'ora di base in altri fusi orari
# e il contrario
#

# Fuso orario base da / a cui convertire
TZBASE = Europe / Athens

# Fusi orari da visualizzare
# Vedi / usr / share / zoneinfo / per altri nomi
TZONES = 'UTC America / Los_Angeles America / New_York Europe / London Europe / Paris'

# Formato di visualizzazione
FORMATO = '% H:% M (% p)% Z% a% m% b% Y'

se ["$ 1"]; poi
  tempo = "$ 1"
altro
  time = `date +% T`
fi

# Mostra l'ora dal fuso orario di input specificato nell'output specificato
# fuso orario
orario dello spettacolo()
{
  Tzin = $ 1
  TZOUT = $ 2

  TZ = $ TZOUT date --date = 'TZ = "' $ TZIN '"' "$ time" + "$ time $ TZIN è $ TZOUT $ FORMAT"
}

per tz in $ TZONES; fare
  showtime $ TZBASE $ tz
fatto

eco

per tz in $ TZONES; fare
  showtime $ tz $ TZBASE
fatto


3

Spesso hai il timestamp nel fuso orario locale e devi convertirlo in tz remoto. Si può fare con:

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

dove:

America/Curacao - remote timezone
MSK - local timezone
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.