ฉันจะให้ "วันที่" ส่งออกเวลาจากเขตเวลาอื่นได้อย่างไร


115

UTCฉันมีเซิร์ฟเวอร์ที่ใช้กับชุดเขตเวลา ดูเหมือนว่าโดยทั่วไปแล้วเป็นวิธีปฏิบัติที่ดี (โปรดแก้ไขฉันหากฉันผิด)

อย่างไรก็ตามเซิร์ฟเวอร์ตัวใดตัวหนึ่งที่ฉันเชื่อมต่อเพื่อscpทำงานEDTและจัดเก็บไฟล์ที่ฉันต้องการคัดลอกในรูปแบบ/path/to/filename/data20120913

ฉันดูที่พยายามrsyncใช้ไฟล์โดยใช้บางสิ่งอย่างเช่น-mtime -1ธงของ find สำหรับไฟล์ที่แก้ไขในวันสุดท้าย แต่ฉันไม่มีโชค

ฉันไม่สนใจที่จะใช้scpเพื่อคัดลอกไฟล์ของวันปัจจุบัน แต่ ณ ตอนนี้มีหน้าต่าง 4 ชั่วโมงที่การทำงานdate +%Y%m%dจะให้วันที่แตกต่างกันในแต่ละเซิร์ฟเวอร์และนั่นทำให้ฉันรำคาญนิดหน่อย

เมื่อมองman dateดูฉันจะเห็นว่าฉันสามารถให้เวลาเป็นเหมือนเวลาUTCแต่ฉันไม่เห็นวิธีที่จะให้มันเป็นเหมือนเขตเวลาอื่นEDT

ฉันคิดว่าฉันสามารถใช้บางอย่างเช่นGNUส่วนขยายวันdate -d 20100909 +%sเพื่อรับวันในวินาทีจากยุคใช้การ4 * 60 * 60คำนวณที่สองด้วยตนเองและดูเกี่ยวกับการแสดงผลที่เป็นวันที่ - แต่แล้วเมื่อเวลาตามฤดูกาลเตะมันจะยังคงปิดชั่วโมง .

มีวิธีที่ง่ายกว่าในการแสดงวันที่ในYYYYMMDDรูปแบบสำหรับEDTบนเซิร์ฟเวอร์ที่ตั้งค่าไว้UTCหรือไม่?


EDT ไม่ใช่เขตเวลาที่รู้จักใน Linux อย่างน้อย ดูของฉัน "ระวัง!" ตอบด้านล่างสำหรับเรื่องราวที่น่าเกลียดทั้งหมด หาก EDT เป็นที่รู้จักในตราสินค้าของคุณ * NIX คุณควรใช้ความระมัดระวังและตรวจสอบสายอักขระเขตเวลาของคุณอีกครั้ง
Mike S

คำตอบ:


175

คุณสามารถตั้งค่าเขตเวลาสำหรับช่วงเวลาของแบบสอบถามได้ดังนี้:

TZ=America/New_York date

บันทึกช่องว่างระหว่างการTZตั้งค่าและdateคำสั่ง ในrcเชลล์เหมือนและเป้าหมายคล้าย Bourne ที่ตั้งค่าTZตัวแปรสำหรับบรรทัดคำสั่งเท่านั้น ในเปลือกหอยอื่น ๆ ( csh, tcsh, fish) คุณก็สามารถใช้envคำสั่งนี้แทน:

env TZ=America/New_York date

TL; DR

บนระบบ Linux เขตเวลาถูกกำหนดในไฟล์ใน/usr/share/zoneinfoไดเรกทอรี โครงสร้างนี้มักเรียกว่า "ฐานข้อมูลโอลสัน" เพื่อเป็นเกียรติแก่ผู้ก่อตั้ง

กฎสำหรับแต่ละเขตเวลาจะถูกกำหนดเป็นบรรทัดไฟล์ข้อความซึ่งจะถูกรวบรวมเป็นไฟล์ไบนารี บรรทัดที่คอมไพล์แล้วให้กำหนดชื่อโซน ช่วงของข้อมูลและเวลาที่ใช้กับโซน ออฟเซ็ตจาก UTC สำหรับเวลามาตรฐาน และสัญกรณ์สำหรับการกำหนดวิธีการเปลี่ยนไปและกลับจากการปรับเวลาตามฤดูกาลจะเกิดขึ้นถ้ามี

ตัวอย่างเช่นไดเรกทอรี "อเมริกา" มีข้อมูลที่จำเป็นสำหรับนิวยอร์กในไฟล์America/New_Yorkตามที่ใช้งานด้านบน

ระวังว่าข้อมูลจำเพาะของโซนที่ไม่มีอยู่จริง (ชื่อไฟล์) จะถูกละเว้นอย่างเงียบ ๆ และเวลา UTC จะถูกรายงาน ตัวอย่างเช่นนี้รายงานเวลาที่ไม่ถูกต้อง:

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

ข้อมูลจำเพาะ UNIX เดี่ยวรุ่น -3 ที่รู้จักกันในชื่อ SUSv3 หรือ POSIX-2001 ตั้งข้อสังเกตว่าเพื่อความสะดวกในการพกพาสตริงอักขระที่ระบุคำอธิบายเขตเวลาควรเริ่มต้นด้วยอักขระโคลอน ดังนั้นเราสามารถเขียน:

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

เป็นวิธีทางเลือกสำหรับข้อกำหนดของเขตเวลาโดยใช้ชื่อพา ธ ไปยังไฟล์คำอธิบาย SUSv3 อธิบายโมเดล POSIX ในรูปแบบนี้สตริงถูกกำหนดเป็น:

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

โดยที่stdเป็นชื่อองค์ประกอบมาตรฐานและdstเป็นหนึ่งในการปรับเวลาตามฤดูกาล แต่ละชื่อประกอบด้วยอักขระสามตัวขึ้นไป ค่าoffsetนี้เป็นค่าบวกสำหรับเขตเวลาทางตะวันตกของเส้นเมริเดียนสำคัญและค่าลบสำหรับทิศตะวันออกของเมอริเดียน ออฟเซ็ตถูกเพิ่มในเวลาท้องถิ่นเพื่อรับ UTC (ชื่อเดิม GMT) startและendเขตเวลาระบุว่าเมื่อเปลี่ยนมาตรฐาน / กลางวันเกิดขึ้น

ตัวอย่างเช่นในสหรัฐอเมริกาตะวันออกเวลามาตรฐานเร็วกว่า UTC 5 ชั่วโมงและเราสามารถระบุEST5EDTแทนAmerica/New_Yorkได้ ทางเลือกเหล่านี้ไม่ได้รับการยอมรับเสมอโดยเฉพาะอย่างยิ่งสำหรับโซนนอกสหรัฐอเมริกาและหลีกเลี่ยงได้ดีที่สุด

HP-UX (UNIX ที่สอดคล้องกับ SUSv3) ใช้กฎเกี่ยวกับใจความ/usr/lib/tztabและชื่อ POSIX เช่น EST5EDT, CST6CDT, MST7MDT, PST8PDT ไฟล์มีกฎทางประวัติศาสตร์ทั้งหมดสำหรับแต่ละโซนเวลาซึ่งคล้ายกับฐานข้อมูล Olson

หมายเหตุ:คุณควรจะสามารถค้นหาเขตเวลาทั้งหมดได้โดยการตรวจสอบไดเรกทอรีต่อไปนี้: /usr/share/zoneinfo.


ไม่แน่ใจว่าฉันผิด แต่exportดูดีกว่าenvคำสั่ง
insign

@JRFerguson - หากไม่รวมเขตเวลาในรายการเช่นลาสเวกัสหรือเนวาดาทางเลือกอื่นในการตรวจสอบความถูกต้องของเวลาคืออะไร
แรงบันดาลใจ

@Motivated หากไม่ได้รวมเมืองหรือรัฐของคุณให้เลือกหนึ่งที่ใช้ข้อมูลโซนเดียวกับของคุณ ตัวอย่างเช่นฉันอยู่ในฟลอริดาซึ่งใช้เขตเวลาเดียวกับนิวยอร์กดังนั้นเครื่องของฉันจึงซิงโครไนซ์กับเวลานิวยอร์ก
JRFerguson

1
@JRFerguson - สมมติว่าบุคคลนั้นทราบเขตเวลาที่หลากหลายและสามารถใช้ทางเลือกเช่น New York ในกรณีของคุณ นั่นเป็นทางเลือกเดียวหรือไม่? ตัวอย่างเช่นฉันไม่ได้อาศัยอยู่ในยุโรปและฉันจะไม่รู้จักเขตเวลาที่ทับซ้อนกัน
แรงบันดาลใจ

1
@Motivated คุณสามารถใช้บางอย่างเช่นเว็บไซต์นี้เพื่อช่วยคุณค้นหาจุดอื่น ๆ ในโซนของคุณ
JRFerguson

33

คุณสามารถทำได้โดยจัดการกับTZตัวแปรสภาพแวดล้อม ต่อไปนี้จะให้เวลาท้องถิ่นสำหรับสหรัฐอเมริกา / ตะวันออกซึ่งจะฉลาดพอที่จะรองรับ DST เมื่อหมุนรอบ:

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

/usr/share/zoneinfoชื่อโซนมาจากไฟล์และไดเรกทอรีภายใน


17

ระวัง! วันที่จะคายเวลาอย่างมีความสุขในเขตเวลาปัจจุบันของคุณถ้าคุณให้เขตเวลานั้นมันไม่รู้จัก

ลองดู:

-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

โปรดทราบว่าไม่มีเขตเวลาที่เรียกว่า EDT ที่จริงแล้ว,

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

ผลตอบแทน

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

และใช้งานได้:

-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

อย่างไรก็ตามหากเพื่อนของคุณอาศัยอยู่ในดินแดนลึกลับของ Gobbledygook และข้อมูลโซนของมันเกิดขึ้นพร้อมกับของคุณเองคุณสามารถมีวันที่ออกเวลาในโซนของ Gobbledygook และมันจะมีความสุขที่จะทำเช่นนั้นด้วยค่าออกเพื่อให้คุณรู้ว่า โซนไม่เป็นที่รู้จักกัน:

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

YMMV: บนกล่อง MacOS / BSD ของฉันTZสตริงที่มีรูปแบบไม่ถูกต้องจะส่งคืนเวลา UTC
Mark Hudson


6

วันไวยากรณ์เป็นความลับและผิดพลาดได้ง่ายซึ่งจะทำให้บรรทัดคำสั่งอุทธรณ์เจ็บปวด ผมจึงได้เขียนสคริปต์ขนาดเล็ก (ผมตั้งชื่อมันworldtime ) ซึ่งจะพิมพ์ระบุ (หรือปัจจุบัน) เวลาจากเวลา Zome ฐาน (หนึ่งในท้องถิ่นของคุณ) ในบางโซนเวลาอื่น ๆ และการสนทนา

นี่มันคือ ปรับให้เข้ากับความต้องการของคุณวางไว้ในเส้นทางของคุณและทำให้มันปฏิบัติได้

#! / bin / ดวลจุดโทษ
#
# พิมพ์เวลา (หรือปัจจุบัน) ที่ระบุจากเวลาพื้นฐานในโซนเวลาอื่น
# และสนทนา
#

# เขตเวลาพื้นฐานจาก / ถึงการแปลง
TZBASE = ยุโรป / เอเธนส์

# เขตเวลาที่จะแสดง
# ดู / usr / share / zoneinfo / สำหรับชื่อเพิ่มเติม
TZONES = 'UTC อเมริกา / Los_Angeles อเมริกา / New_York ยุโรป / ลอนดอนยุโรป / ปารีส'

# รูปแบบการแสดงผล
FORMAT = '% H:% M (% p)% Z% a% m% b% Y'

ถ้า ["$ 1"]; แล้วก็
  เวลา = "$ 1"
อื่น
  time = `date +% T`
Fi

# แสดงเวลาจากโซนเวลาอินพุตที่ระบุในเอาต์พุตที่ระบุ
# เขตเวลา
เวลาแสดง()
{
  TZIN = $ 1
  TZOUT = $ 2

  TZ = $ TZOUT date - วันที่ = 'TZ = "' $ TZIN '"' "$ time" + "$ time $ TZIN คือ $ TZOUT $ FORMAT"
}

สำหรับ tz ใน $ TZONES; ทำ
  โชว์ $ TZBASE $ tz
เสร็จแล้ว

เสียงสะท้อน

สำหรับ tz ใน $ TZONES; ทำ
  โชว์ $ tz $ TZBASE
เสร็จแล้ว


3

บ่อยครั้งที่คุณมีการประทับเวลาในเขตเวลาท้องถิ่นและคุณจำเป็นต้องแปลงเป็นระยะไกล tz สามารถทำได้ด้วย:

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

ที่อยู่:

America/Curacao - remote timezone
MSK - local timezone
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.