Mengapa TZ = UTC-8 menghasilkan tanggal yang UTC + 8?

25

Waktu sekarang di Los Angeles adalah 18:05. Tetapi ketika saya berlari TZ=UTC-8 date --iso=ns, saya mendapatkan:

2013-12-07T10:05:37,788173835+0800

Utilitas tanggal memberi tahu saya bahwa waktunya 10:05, dan bahkan mengatakan bahwa itu melaporkannya sebagai UTC + 8. Mengapa?

Alex Henrie
sumber

Jawaban:

33

Alasannya adalah yang TZ=UTC-8ditafsirkan sebagai zona waktu POSIX . Dalam format zona waktu POSIX, 3 huruf adalah singkatan zona waktu (yang berubah-ubah) dan angkanya adalah jumlah jam zona waktu berada di belakang UTC. Jadi UTC-8berarti zona waktu disingkat "UTC" yaitu −8 jam di belakang UTC asli, atau UTC + 8 jam.

(Ini berfungsi seperti itu karena Unix dikembangkan di AS, yang berada di belakang UTC. Format ini memungkinkan zona waktu AS direpresentasikan sebagai EST5, CST6, dll.)

Anda dapat melihat bahwa itulah yang terjadi dengan contoh-contoh ini:

$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800

-0800Format zona waktu ISO mengambil pendekatan yang berlawanan, dengan -menunjukkan zona berada di belakang UTC, dan +menunjukkan zona berada di depan UTC.

cjm
sumber
Ah jadi yang benar-benar saya inginkan adalah TZ=PST+8 date. Terima kasih. Saya juga menemukan penjelasan ini di bawah man timezone: "String std menentukan nama zona waktu dan harus tiga atau lebih karakter alfabet. String offset segera mengikuti std dan menentukan nilai waktu yang akan ditambahkan ke waktu lokal untuk mendapatkan Waktu Universal Terkoordinasi ( UTC). Offsetnya positif jika zona waktu lokal di barat Prime Meridian dan negatif jika timur. Jamnya harus antara 0 dan 24, dan menit dan detik 0 dan 59. "
Alex Henrie
3
@Alex tidak, apa yang Anda inginkan sebenarnya TZ=America/Los_Angeles. Anda lupa bahwa waktu Pasifik -7 selama waktu musim panas.
Matt Johnson-Pint
3
@MattJohnson, maksud Anda TZ=:America/Los_Angeles. Tanda titik dua menunjukkan bahwa ini adalah file zona waktu Olson. Dan dalam komentar lain, dia mengatakan dia ingin mengabaikan waktu musim panas, yang tidak akan berhasil.
cjm
@ cjm, Terima kasih, Anda benar tentang titik dua, dan saya belum melihat komentar itu.
Matt Johnson-Pint
Amerika, sebabkan dunia jika itu berarti kita harus menjadi EST-5 CST-6.
Evan Carroll
7

Setiap kali Anda menentukan zona waktu dalam format +/- 00:00, Anda menentukan offset , bukan zona waktu yang sebenarnya. Dari GNU libc dokumentasi (yang mengikuti standar POSIX):

Offset menentukan nilai waktu yang harus Anda tambahkan ke waktu lokal untuk mendapatkan nilai Waktu Universal Terkoordinasi. Ini memiliki sintaks seperti [+ | -] jj [: mm [: ss]]. Ini positif jika zona waktu lokal di sebelah barat Meridian Utama dan negatif jika zona timur. Jam harus antara 0 dan 23, dan menit dan detik antara 0 dan 59.

Inilah sebabnya mengapa tampaknya kebalikan dari apa yang Anda harapkan.

jordanm
sumber
2

Why?

Karena POSIX memerlukannya .

Jika didahului oleh '-', zona waktu akan berada di timur Meridian Utama; jika tidak, itu harus barat (yang dapat ditunjukkan dengan '+' sebelumnya opsional).

Jadi, ini akan memberi waktu dekat [1] Los Angeles (dengan label 3 huruf untuk teks zona waktu):

$ TZ=ANY8 date "+%Y-%m-%d %H:%M:%S %Z%z"
2016-04-23 10:47:12 ANY-0800

$ TZ=GMT+8 date "+%Y-%m-%d %H:%M:%S %Z%z"
2016-04-23 10:47:12 GMT-0800

Dan ini harus memberi waktu dekat Shanghai, Chinaatau Perth, Australia:

$ TZ=ANY-8 date "+%Y-%m-%d %H:%M:%S %Z%z"
2016-04-24 02:47:12 ANY+0800

$ TZ=CST-8 date "+%Y-%m-%d %H:%M:%S %Z%z"
2016-04-23 02:47:12 CST+0800

[1] Dekat karena mungkin ada beberapa DST (Daylight Saving Time) yang berlaku yang menggeser "waktu lokal" yang sebenarnya.


sumber
1

Sebagai metode alternatif, Anda dapat menggunakan perintah zdumpuntuk menampilkan waktu saat ini di zona waktu + offset lainnya.

Zdump mencetak waktu saat ini di setiap zonename yang disebutkan pada baris perintah.

Aturan yang sama berlaku dengan zona waktu; sebelah barat meridian utama berada "di belakang" sementara di sebelah timur "di depan".

Contoh

$ zdump PST PST Sabtu 7 Des 03:25:27 2013 PST

Saya membuat skrip ini untuk menunjukkan beberapa zona waktu + offset yang ingin kami gunakan zdumpdan dateagar kami dapat membandingkannya.

$ cat cmd.bash
#!/bin/bash

printf "\ndate: %s\n\n" "$(date)"

for tz in EST PST PST+8 PST-8 UTC UTC+8 UTC-8; do
  echo "-- timezone $tz"
  printf "zdump: %s\n" "$(zdump $tz)"
  printf "date:         %s\n" "$(TZ=$tz date +'%a %b %d %T %Y - (%Z %z)')"
  echo ""
done

Kemudian ketika Anda menjalankannya, Anda dapat melihat perbandingan zdumpuntuk date:

$ ./cmd.bash 

date: Sat Dec  7 02:59:05 EST 2013

-- timezone EST
zdump: EST  Sat Dec  7 02:59:05 2013 EST
date:         Sat Dec 07 02:59:05 2013 - (EST -0500)

-- timezone PST
zdump: PST  Sat Dec  7 07:59:05 2013 PST
date:         Sat Dec 07 07:59:05 2013 - (PST +0000)

-- timezone PST+8
zdump: PST+8  Fri Dec  6 23:59:05 2013 PST
date:         Fri Dec 06 23:59:05 2013 - (PST -0800)

-- timezone PST-8
zdump: PST-8  Sat Dec  7 15:59:05 2013 PST
date:         Sat Dec 07 15:59:05 2013 - (PST +0800)

-- timezone UTC
zdump: UTC  Sat Dec  7 07:59:05 2013 UTC
date:         Sat Dec 07 07:59:05 2013 - (UTC +0000)

-- timezone UTC+8
zdump: UTC+8  Fri Dec  6 23:59:05 2013 UTC
date:         Fri Dec 06 23:59:05 2013 - (UTC -0800)

-- timezone UTC-8
zdump: UTC-8  Sat Dec  7 15:59:05 2013 UTC
date:         Sat Dec 07 15:59:05 2013 - (UTC +0800)
slm
sumber
Saya sebenarnya mencoba untuk mendapatkan waktu saat ini di Waktu Standar Pasifik, mengabaikan Daylight Savings.
Alex Henrie
1
Saya harus mengundurkan diri karena Anda menduga "UTC-8" salah. Benar, itu hanya tidak melakukan apa yang diharapkan pengguna. Saya tidak merasa itu menjawab pertanyaan mengapa itu bekerja seperti itu.
jordanm
@jordanm - lihat bersih-bersih.
slm
1
Itu masih menjelaskan apa yang terjadi tetapi tidak mengapa dan "mengapa" adalah apa yang diminta OP. Saya akan menghapus downvote saya, tetapi saya masih merasa itu bukan jawaban yang baik untuk pertanyaan itu.
jordanm