Bagaimana saya dapat `date` output waktu dari zona waktu yang berbeda?

115

Saya memiliki server yang berjalan dengan zona waktu diatur ke UTC. Sepertinya itu adalah praktik yang baik (tolong perbaiki jika saya salah).

Bagaimanapun, salah satu server yang saya sambungkan, untuk scpfile, sedang berjalan EDTdan menyimpan file yang saya perlu salin dalam format/path/to/filename/data20120913

Saya melihat mencoba rsyncfile menggunakan sesuatu seperti -mtime -1flag find untuk file yang dimodifikasi pada hari terakhir, tapi saya tidak beruntung.

Saya tidak keberatan hanya menggunakan scpuntuk menyalin file hari ini, tetapi pada saat ini ada jendela 4 jam di mana menjalankan date +%Y%m%dakan memberikan hari yang berbeda pada setiap server dan itu sedikit mengganggu saya.

Melihat melalui man datesaya melihat bahwa saya dapat memiliki output waktu sebagai UTC, tetapi saya tidak melihat cara untuk memiliki output sebagai zona waktu lain sepertiEDT

Saya kira saya juga bisa menggunakan sesuatu seperti GNUekstensi tanggal date -d 20100909 +%suntuk mendapatkan tanggal dalam hitungan detik dari zaman, menerapkan 4 * 60 * 60perhitungan manual kedua, dan melihat tentang menjadikannya sebagai tanggal - tetapi kemudian ketika waktu siang hari menendang di dalamnya masih akan menjadi satu jam libur .

Apakah ada cara yang lebih sederhana untuk menampilkan tanggal dalam YYYYMMDDformat untuk EDTpada server yang diatur ke UTC?

cwd
sumber
Setidaknya EDT bukan zona waktu yang dikenali di Linux. Lihat "Hati-hati!" jawaban di bawah ini untuk keseluruhan cerita jelek. Jika EDT dikenali dari merek * NIX Anda, Anda harus tetap berhati-hati dan memeriksa ulang string zona waktu Anda.
Mike S

Jawaban:

175

Anda dapat menetapkan zona waktu selama durasi kueri, dengan demikian:

TZ=America/New_York date

Perhatikan spasi putih antara TZpengaturan dan dateperintah. Dalam rcshell Bourne-like dan -like, yang menetapkan TZvariabel hanya untuk baris perintah. Dalam kerang lainnya ( csh, tcsh, fish), Anda dapat selalu menggunakan envperintah sebagai gantinya:

env TZ=America/New_York date

tl; dr

Di sistem Linux. zona waktu didefinisikan dalam file dalam /usr/share/zoneinfodirektori. Struktur ini sering disebut sebagai "database Olson" untuk menghormati kontributor pendiri.

Aturan untuk setiap zona waktu didefinisikan sebagai baris file teks yang kemudian dikompilasi menjadi file biner. Garis yang dikompilasi, tentukan nama zona; rentang data dan waktu selama zona tersebut berlaku; offset dari UTC untuk waktu standar; dan notasi untuk menentukan bagaimana transisi ke-dan-dari waktu musim panas terjadi, jika berlaku.

Misalnya, direktori "Amerika" berisi informasi yang diperlukan untuk New York dalam file America/New_Yorkseperti yang digunakan, di atas.

Berhati-hatilah bahwa spesifikasi zona yang tidak ada (nama file) diabaikan secara diam-diam dan waktu UTC dilaporkan. Misalnya, ini melaporkan waktu yang salah:

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

Spesifikasi UNIX Tunggal, versi-3, dikenal sebagai SUSv3 atau POSIX-2001, mencatat bahwa untuk portabilitas, string karakter yang mengidentifikasi deskripsi zona waktu harus dimulai dengan karakter titik dua. Jadi, kita juga bisa menulis:

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

Sebagai metode alternatif untuk spesifikasi zona waktu menggunakan pathname ke file deskripsi, SUSv3 menjelaskan model POSIX. Dalam format ini, string didefinisikan sebagai:

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

di mana stdadalah nama komponen standar dan dstyang hemat di siang hari. Setiap nama terdiri dari tiga karakter atau lebih. Nilai offsetpositif untuk zona waktu di barat meridian utama dan negatif untuk zona timur meridian. Offset ditambahkan ke waktu lokal untuk mendapatkan UTC (sebelumnya dikenal sebagai GMT). Kolom startdan endwaktu menunjukkan kapan transisi standar / siang hari terjadi.

Misalnya, di Amerika Serikat bagian Timur, waktu standar adalah 5 jam lebih awal dari UTC, dan kami dapat menentukan EST5EDTsebagai pengganti America/New_York. Namun, alternatif ini tidak selalu diakui, terutama untuk zona di luar Amerika Serikat dan sebaiknya dihindari.

HP-UX (sebuah UNIX yang memenuhi SUSv3) menggunakan aturan tekstual /usr/lib/tztabdan nama-nama POSIX seperti EST5EDT, CST6CDT, MST7MDT, PST8PDT. File tersebut mencakup semua aturan historis untuk setiap zona waktu, mirip dengan basis data Olson.

CATATAN: Anda harus dapat menemukan semua zona waktu dengan memeriksa direktori berikut: /usr/share/zoneinfo.

JRFerguson
sumber
tidak yakin apakah saya salah, tetapi exportterlihat lebih baik daripada envperintah
insign
@JRFerguson - Jika zona waktu tidak termasuk dalam daftar, mis. Las Vegas atau Nevada, apa saja alternatif dalam memvalidasi waktu?
Termotivasi
@ Dimotivasi Jika kota atau negara bagian Anda tidak termasuk, pilih kota yang menggunakan info zona yang sama seperti milik Anda. Misalnya, saya di Florida, yang menggunakan zona waktu yang sama dengan New York, jadi mesin saya menyinkronkan ke waktu New York.
JRFerguson
1
@JRFerguson - Itu mengasumsikan bahwa orang tersebut mengetahui berbagai zona waktu dan dapat menggunakan alternatif misalnya New York dalam kasus Anda. Apakah itu satu-satunya pilihan? Misalnya, saya tidak tinggal di Eropa dan saya tidak akan tahu zona waktu yang tumpang tindih.
Termotivasi
1
@Motivasi Anda dapat menggunakan sesuatu seperti situs ini untuk membantu Anda menemukan poin lain di zona Anda.
JRFerguson
33

Anda dapat melakukan ini dengan memanipulasi TZvariabel lingkungan. Berikut ini akan memberi Anda waktu lokal untuk AS / Timur, yang juga akan cukup pintar untuk menangani DST ketika itu bergulir:

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

Nama zona berasal dari file dan direktori di dalamnya /usr/share/zoneinfo.

James Sneeringer
sumber
17

Hati-hati! Tanggal akan dengan senang hati meludahkan waktu di zona waktu CURRENT Anda, jika Anda memberinya zona waktu yang tidak dikenali.

Lihat ini:

-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

Perhatikan bahwa tidak ada zona waktu yang disebut EDT. Faktanya,

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

kembali

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

Dan ini bekerja:

-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

Namun, jika teman Anda tinggal di tanah mistik Gobbledygook dan info zonanya bertepatan dengan milik Anda, Anda dapat membuat tanggal keluaran waktu di zona Gobbledygook dan dengan senang hati akan melakukannya dengan sedikit nilai keluar untuk memberi tahu Anda bahwa zona tidak diketahui:

-bash-4.2$ TZ=Gobbledygook date
Wed Feb 18 19:37:36 Gobbledygook 2015
-bash-4.2$ echo $?
0
Mike S
sumber
YMMV: pada kotak MacOS / BSD saya, TZstring yang salah mengembalikan waktu UTC.
Mark Hudson
8
TODAY=$(TZ=":US/Eastern" date)
echo $TODAY
Lin
sumber
6

The tanggal sintaks misterius dan rawan kesalahan, yang membuat baris perintah pemanggilan sakit. Karena itu saya menulis skrip kecil (saya menamakannya worldtime ), yang akan mencetak waktu yang ditentukan (atau saat ini) dari waktu dasar zome (yang lokal Anda) di beberapa zona waktu lain dan sebaliknya.

Ini dia. Sesuaikan agar sesuai dengan kebutuhan Anda, letakkan di jalur Anda, dan membuatnya dapat dieksekusi.

#! / bin / sh
#
# Cetak waktu yang ditentukan (atau saat ini) dari waktu dasar di zona waktu lain
# dan sebaliknya
#

# Zona waktu basis dari / yang akan dikonversi
TZBASE = Eropa / Athena

# Zona waktu untuk ditampilkan
# Lihat / usr / share / zoneinfo / untuk lebih banyak nama
TZONES = 'UTC America / Los_Angeles America / New_York Europe / London Europe / Paris'

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

jika ["$ 1"]; kemudian
  waktu = "$ 1"
lain
  waktu = `tanggal +% T`
fi

# Tampilkan waktu dari zona waktu input yang ditentukan dalam output yang ditentukan
# zona waktu
waktu pertunjukan()
{
  TZIN = $ 1
  TZOUT = $ 2

  TZ = $ TZOUT tanggal --tanggal = 'TZ = "' $ TZIN '"' "$ time" + "$ time $ TZIN adalah $ TZOUT $ FORMAT"
}

untuk tz dalam $ TZONES; melakukan
  waktu pertunjukan $ TZBASE $ tz
Selesai

gema

untuk tz dalam $ TZONES; melakukan
  waktu tayang $ tz $ TZBASE
Selesai

Diomidis Spinellis
sumber
3

Seringkali Anda memiliki stempel waktu di zona waktu lokal dan Anda harus mengubahnya menjadi tz jarak jauh. Itu bisa dilakukan dengan:

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

dimana:

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