ทำไมถึงมีความแตกต่างกับ Unix วันที่ระหว่าง 2 และ 3 เดือน


16

สิ่งนี้เป็นไปได้อย่างไรและฉันจะจัดการกับมันอย่างไร ฉันสร้างสคริปต์สำรองที่ขึ้นอยู่กับ Unix dateและพบข้อบกพร่องที่น่าสนใจ:

[root@web000c zfs_test]# date +%y-%m-%d --date='2 months ago'
14-04-01
[root@web000c zfs_test]# date +%y-%m-%d --date='3 months ago'
14-02-28
[root@web000c zfs_test]# date
Sun Jun  1 00:08:50 CEST 2014

มันอาจจะเป็นปีอธิกสุรทิน / 29 กุมภาพันธ์ข้อบกพร่อง? ไม่น่าเป็นไปได้ในเครื่องมือเช่นนี้date...
Mark Henderson

คำตอบ:


44

คุณเห็นพฤติกรรมนี้เนื่องจากเวลาฤดูร้อน (เวลาออมแสง)

เนื่องจากขณะนี้คุณอยู่ในช่วงฤดูร้อนซึ่งนาฬิกาของคุณอยู่ข้างหน้าหนึ่งชั่วโมงเมื่อคุณขอเวลาสามเดือนที่ผ่านมาหลังเที่ยงคืนของวันที่ 1 มิถุนายนเวลาสิ้นสุดลงเป็น "ชั่วโมงก่อนหน้า" หนึ่งชั่วโมงเพราะไม่ใช่เวลาฤดูร้อนที่สาม หลายเดือนก่อน.

เอกสารวันที่ของ GNU แนะนำให้หลีกเลี่ยงสิ่งนี้โดยใช้เวลา 12.00 น. และวันที่ 15 ของเดือนเป็นจุดเริ่มต้นเมื่อขอวันหรือเดือนสัมพัทธ์ตามลำดับ ตัวอย่างเช่น:

date +%y-%m-%d --date="$(date +%Y-%m-15) -3 month"

ขอขอบคุณ. ใช่ว่า "3 เดือนที่ผ่านมา" มาโดย[root@web000c zfs_test]# date +%y-%m-%d --date='3 months ago' 14-03-01 [root@web000c zfs_test]# date Sun Jun 1 01:00:15 CEST 2014
01:00

Doh! ฉันคิดว่าฉันจำเป็นต้องอ่านบทภาพยนตร์บางเรื่องเพราะฉันสงสัยว่าฉันมองข้ามข้อเสนอแนะในdateการใช้งาน
Caleb

14

หากการกำหนดเวลาสัมบูรณ์เป็นข้อกังวลหลักของคุณอาจเป็นการดีที่สุดที่จะหลีกเลี่ยงUTCเนื่องจากมีไว้สำหรับจุดประสงค์นั้น คำตอบของ Michael นั้นมีประโยชน์มากเมื่อคุณต้องทำงานกับปัญหา แต่โดยทั่วไปแล้วคุณควรหลีกเลี่ยงปัญหาที่คุณสามารถทำได้

เมื่อระบบของคุณไม่ได้ตั้งค่าเป็น UTC ตามค่าเริ่มต้นวิธีที่ง่ายที่สุดในการผ่านเขตเวลาในคือโดยคำนำหน้าคำสั่งของคุณด้วยTZตัวแปรสภาพแวดล้อม สิ่งนี้ จำกัด การสลับโซนไปที่คำสั่งเดียวและป้องกันไม่ให้ตัวแปรรั่วไหลในคำสั่งที่ตามมา

$ NOW=$(date '+%s')
$ date -d @$NOW
Wed Jun 11 23:44:35 EDT 2014
$ TZ=UTC date -d @$NOW
Thu Jun 12 03:44:35 UTC 2014

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

$ export TZ=UTC
$ date -d @$NOW
Thu Jun 12 03:44:35 UTC 2014
$ TZ=EDT date -d @$NOW
Thu Jun 12 03:44:35 EDT 2014

-3

ในปีนี้คอมพิวเตอร์ของคุณคิดว่ากำลังใช้งานและในวันที่คุณเลือกสำหรับการทดสอบ "1 เดือนที่ผ่านมา 2 เดือนที่ผ่านมาและ 3 เดือนที่ผ่านมาใช่ - เป็นไปได้ว่าจะมีการตรวจจับ 29 กุมภาพันธ์เสมอไป ข้อผิดพลาด แต่ ..

ตอนนี้วันนี้ไม่ใช่ 2014-06-01 ลองอีกครั้ง. ตั้งวันที่คอมพิวเตอร์เป็น 2013-06-01 ลองอีกครั้ง.
ตั้งวันที่คอมพิวเตอร์เป็น 2014-09-01 ลองอีกครั้ง.


6
หากคุณระบุวันที่ในMDYรูปแบบอเมริกันโปรดใช้/es เพื่อแยก ที่ดียิ่งขึ้นในขณะที่เราเป็นประชาคมระหว่างประเทศที่นี่ใช้วันที่ ISO 2014-09-01ที่เหมาะสมเช่น
glglgl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.