Tại sao TZ = UTC-8 tạo ra ngày là UTC + 8?


25

Thời gian hiện tại ở Los Angeles là 18:05. Nhưng khi tôi chạy TZ=UTC-8 date --iso=ns, tôi nhận được:

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

Tiện ích ngày cho tôi biết rằng thời gian là 10:05 và thậm chí nói rằng nó báo cáo là UTC + 8. Tại sao?

Câu trả lời:


33

Lý do là TZ=UTC-8được hiểu là múi giờ POSIX . Trong định dạng múi giờ POSIX, 3 chữ cái là chữ viết tắt múi giờ (tùy ý) và số là số giờ múi giờ đứng sau UTC. Vì vậy, UTC-8có nghĩa là múi giờ viết tắt là "UTC", chậm hơn 8 giờ so với UTC thực, hoặc UTC + 8 giờ.

(Nó hoạt động theo cách đó vì Unix được phát triển ở Hoa Kỳ, đứng sau UTC. Định dạng này cho phép các múi giờ của Hoa Kỳ được thể hiện dưới dạng EST5, CST6, v.v.)

Bạn có thể thấy đó là những gì đang xảy ra bởi những ví dụ này:

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

-0800Định dạng múi giờ ISO có cách tiếp cận ngược lại, với việc -chỉ ra vùng nằm phía sau UTC và +cho biết vùng này nằm trước UTC.


Ah vì vậy những gì tôi thực sự muốn là TZ=PST+8 date. Cảm ơn. Tôi cũng tìm thấy lời giải thích này trong man timezone: "Chuỗi std chỉ định tên của múi giờ và phải có ba ký tự chữ cái trở lên. Chuỗi bù ngay sau std và chỉ định giá trị thời gian được thêm vào giờ địa phương để lấy Giờ quốc tế phối hợp ( UTC). Phần bù là dương nếu múi giờ địa phương ở phía tây của Kinh tuyến gốc và âm nếu là hướng đông. Giờ phải nằm trong khoảng từ 0 đến 24, và phút và giây 0 và 59. "
Alex Henrie

3
@Alex không, những gì bạn thực sự muốn là TZ=America/Los_Angeles. Bạn đang quên rằng thời gian Thái Bình Dương là -7 trong thời gian tiết kiệm ánh sáng ban ngày.
Matt Johnson-Pint

3
@MattJohnson, ý bạn là TZ=:America/Los_Angeles. Dấu hai chấm cho biết đó là tệp múi giờ Olson. Và trong một bình luận khác, anh ta đề cập rằng anh ta muốn bỏ qua thời gian tiết kiệm ánh sáng ban ngày, điều đó sẽ không làm được.
cjm

@cjm, Cảm ơn, bạn nói đúng về dấu hai chấm và tôi chưa thấy bình luận đó.
Matt Johnson-Pint

Mỹ, gây ra thế giới nếu nó có nghĩa là chúng ta phải như vậy EST-5 CST-6.
Evan Carroll

7

Bất cứ khi nào bạn chỉ định múi giờ theo định dạng +/- 00:00, bạn sẽ chỉ định một phần , không phải múi giờ thực tế. Từ GNU libc tài liệu (theo tiêu chuẩn POSIX):

Giá trị bù chỉ định giá trị thời gian bạn phải thêm vào giờ địa phương để nhận giá trị Giờ phối hợp quốc tế. Nó có cú pháp như [+ | -] hh [: mm [: ss]]. Điều này là tích cực nếu múi giờ địa phương ở phía tây của Kinh tuyến gốc và âm nếu là phía đông. Giờ phải nằm trong khoảng từ 0 đến 23, và phút và giây trong khoảng từ 0 đến 59.

Đây là lý do tại sao nó dường như là đảo ngược của những gì bạn mong đợi.


2

Why?

Bởi vì POSIX yêu cầu nó .

Nếu đứng trước '-', múi giờ sẽ ở phía đông của Kinh tuyến gốc; mặt khác, nó sẽ ở phía tây (có thể được chỉ định bởi một '+' tùy chọn trước).

Vì vậy, điều này sẽ cho thời gian gần [1] Los Angeles (với bất kỳ nhãn 3 chữ cái nào cho văn bản múi giờ):

$ 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

Và điều này sẽ cho thời gian gần Shanghai, Chinahoặc 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] Gần vì có thể có một số DST (Giờ tiết kiệm ánh sáng ban ngày) có hiệu lực làm thay đổi "giờ địa phương" thực tế.


1

Là một phương pháp thay thế, bạn có thể sử dụng lệnh zdumpđể hiển thị thời gian hiện tại trong các múi giờ + offset khác.

Zdump in thời gian hiện tại trong mỗi tên zon có tên trên dòng lệnh.

Các quy tắc tương tự áp dụng với các múi giờ; phía tây của kinh tuyến gốc là "phía sau" trong khi phía đông là "phía trước".

Thí dụ

$ zdump PST PST Sat Ngày 7 tháng 12 03:25:27 2013 PST

Tôi đã tạo tập lệnh này để hiển thị một số múi giờ + độ lệch mà chúng tôi quan tâm khi sử dụng zdumpdatevì vậy chúng tôi có thể so sánh chúng.

$ 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

Sau đó, khi bạn chạy nó bạn sẽ nhìn thấy so sánh zdumpvới 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)

Tôi thực sự đang cố gắng để có được thời gian hiện tại theo Giờ chuẩn Thái Bình Dương, bỏ qua Tiết kiệm ánh sáng ban ngày.
Alex Henrie

1
Tôi đã phải đánh giá thấp cái này vì bạn đoán rằng "UTC-8" không chính xác. Đó là chính xác, nó chỉ không làm những gì người dùng mong đợi. Tôi không cảm thấy rằng nó trả lời câu hỏi là tại sao nó hoạt động theo cách đó.
jordanm

@jordanm - Xem dọn dẹp.
slm

1
Nó vẫn giải thích những gì đang xảy ra nhưng không phải tại sao và "tại sao" là những gì OP đang hỏi. Tôi sẽ xóa downvote của mình nhưng tôi vẫn không cảm thấy đó là một câu trả lời hay cho câu hỏi.
jordanm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.