ทำไม TZ = UTC-8 สร้างวันที่ซึ่งเป็น UTC + 8?


25

เวลาในปัจจุบันในลอสแองเจลิสคือ 18:05 แต่เมื่อฉันวิ่งTZ=UTC-8 date --iso=nsฉันจะได้รับ:

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

ยูทิลิตี้วันที่บอกฉันว่าเวลาคือ 10:05 และยังบอกว่ามันรายงานว่าเป็น UTC + 8 ทำไม?

คำตอบ:


33

เหตุผลก็คือว่าTZ=UTC-8จะถูกตีความว่าเป็นโซนเวลา POSIX ในรูปแบบเขตเวลา POSIX ตัวอักษร 3 ตัวเป็นตัวย่อของเขตเวลา (ซึ่งเป็นกฎเกณฑ์) และจำนวนคือจำนวนชั่วโมงที่เขตเวลาอยู่หลัง UTC ดังนั้นUTC-8หมายถึงเขตเวลาย่อ "UTC" ซึ่งอยู่หลัง behind8 ชั่วโมงจริง UTC หรือ UTC + 8 ชั่วโมง

(ใช้งานได้เพราะ Unix ได้รับการพัฒนาในสหรัฐอเมริกาซึ่งอยู่หลัง UTC รูปแบบนี้อนุญาตให้เขตเวลาของสหรัฐอเมริกาแสดงเป็น EST5, CST6 และอื่น ๆ )

คุณสามารถเห็นว่าเป็นสิ่งที่เกิดขึ้นจากตัวอย่างเหล่านี้:

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

-0800รูปแบบเขตเวลาISO ใช้แนวทางตรงกันข้ามโดยมีการ-ระบุว่าโซนอยู่หลัง UTC และ+แสดงว่าโซนนั้นอยู่ข้างหน้าของ UTC


Ah TZ=PST+8 dateดังนั้นสิ่งที่ผมอยากเป็น ขอบคุณ ฉันยังพบคำอธิบายนี้ภายใต้man timezone: "สตริง std ระบุชื่อของเขตเวลาและจะต้องเป็นตัวอักษรสามตัวหรือมากกว่าตัวอักษรสตริงชดเชยทันทีตาม std และระบุค่าเวลาที่จะเพิ่มลงในเวลาท้องถิ่นเพื่อประสานงานเวลาสากล ( UTC) ออฟเซ็ตจะเป็นค่าบวกหากเขตเวลาท้องถิ่นเป็นทิศตะวันตกของ Prime Meridian และค่าลบหากเป็นทิศตะวันออกชั่วโมงจะต้องอยู่ระหว่าง 0 ถึง 24 และนาทีและวินาทีและวินาที 0 และ 59 "
Alex Henrie

3
@ Alex TZ=America/Los_Angelesไม่มีสิ่งที่คุณต้องการจริงๆคือ คุณลืมว่าเวลาแปซิฟิกคือ -7 ในช่วงเวลากลางวัน
Matt Johnson-Pint

3
@MattJohnson TZ=:America/Los_Angelesคุณหมายถึง เครื่องหมายโคลอนระบุว่าเป็นไฟล์เขตเวลา Olson และในความคิดเห็นอื่นเขากล่าวว่าเขาต้องการละเว้นการปรับเวลาตามฤดูกาลซึ่งจะไม่ทำ
cjm

@cjm ขอบคุณคุณพูดถูกเกี่ยวกับลำไส้ใหญ่และฉันไม่เห็นความคิดเห็นนั้น
Matt Johnson-Pint

EST-5 CST-6อเมริกาสาเหตุฉโลกถ้ามันหมายความว่าเราจะต้องมีการ
Evan Carroll

7

เมื่อใดก็ตามที่คุณระบุเขตเวลาในรูปแบบ +/- 00:00 คุณจะระบุการชดเชยไม่ใช่เขตเวลาจริง จากGNU libc เอกสาร (ซึ่งเป็นไปตามมาตรฐาน POSIX):

ออฟเซ็ตระบุค่าเวลาที่คุณต้องเพิ่มในเวลาท้องถิ่นเพื่อรับค่า Coordinated Universal Time มันมีรูปแบบเช่น [+ | -] hh [: mm [: ss]] นี่เป็นบวกถ้าเขตเวลาท้องถิ่นอยู่ทางทิศตะวันตกของนายกรัฐมนตรีเมริเดียนและลบหากอยู่ทางตะวันออก ชั่วโมงต้องอยู่ระหว่าง 0 ถึง 23 และนาทีและวินาทีระหว่าง 0 ถึง 59

นี่คือเหตุผลที่ดูเหมือนจะย้อนกลับของสิ่งที่คุณคาดหวัง


2

Why?

เพราะPOSIX ต้องใช้มัน

หากนำหน้าด้วย '-' เขตเวลาจะเป็นทิศตะวันออกของนายกรัฐมนตรีเมริเดียน มิฉะนั้นจะเป็นตะวันตก (ซึ่งอาจระบุด้วยตัวเลือกก่อนหน้า '+')

ดังนั้นจะให้เวลาใกล้[1] Los Angeles (มีป้ายกำกับตัวอักษร 3 ตัวสำหรับข้อความเขตเวลา):

$ 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

และนี่ควรให้เวลาใกล้Shanghai, Chinaหรือ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] ใกล้เพราะอาจมี DST (ปรับเวลาตามฤดูกาล) บางอย่างซึ่งเปลี่ยน "เวลาท้องถิ่น" ตามจริง


1

เป็นวิธีทางเลือกคุณสามารถใช้คำสั่งzdumpเพื่อแสดงเวลาปัจจุบันในเขตเวลาอื่น + ออฟเซ็ต

Zdump พิมพ์เวลาปัจจุบันในแต่ละชื่อโซนบนบรรทัดคำสั่ง

ใช้กฎเดียวกันกับเขตเวลา ทางตะวันตกของเส้นเมอริเดียนที่สำคัญคือ "ข้างหลัง" ในขณะที่ทางตะวันออกเป็น "ข้างหน้า"

ตัวอย่าง

$ zdump PST PST วันที่ 7 ธ.ค. 03:25:27 2013 PST

ฉันสร้างสคริปต์นี้เพื่อแสดงเขตเวลา + ออฟเซ็ตหลายแห่งที่เราสนใจใช้zdumpและdateเพื่อให้เราสามารถเปรียบเทียบได้

$ 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

จากนั้นเมื่อคุณเรียกใช้คุณจะเห็นการเปรียบเทียบของzdumpกับ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)

ที่จริงฉันพยายามรับเวลาปัจจุบันในเวลามาตรฐานแปซิฟิกโดยไม่สนใจการออมตามฤดูกาล
Alex Henrie

1
ฉันต้องลงคะแนนเพราะคุณเดาว่า "UTC-8" ไม่ถูกต้อง ถูกต้องมันไม่ได้ทำสิ่งที่ผู้ใช้คาดหวัง ฉันไม่รู้สึกว่ามันตอบคำถามว่าทำไมมันถึงทำงานแบบนั้น
จอร์แดน

@ jordanm - ดูการทำความสะอาด
slm

1
มันยังคงอธิบายสิ่งที่เกิดขึ้น แต่ไม่ใช่เพราะอะไรและ "ทำไม" คือสิ่งที่ OP ขอ ฉันจะลบ downvote ของฉัน แต่ฉันก็ยังไม่รู้สึกว่ามันเป็นคำตอบที่ดีสำหรับคำถาม
จอร์แดน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.