ใน postgres, timestamp with time zone
สามารถย่อเป็นtimestamptz
และเป็นtimestamp without time zone
timestamp
ฉันจะใช้ชื่อประเภทสั้นลงเพื่อความเรียบง่าย
การรับ Unix timestamp จาก postgres timestamptz
like now()
นั้นง่ายอย่างที่คุณพูดเพียง:
select extract(epoch from now());
ที่จริงสิ่งที่คุณจำเป็นต้องรู้เกี่ยวกับการรับเวลาที่แน่นอนจากสิ่งที่ประเภทรวมทั้งtimestamptz
now()
สิ่งที่ซับซ้อนเมื่อคุณมีtimestamp
เขตข้อมูลเท่านั้น
เมื่อคุณใส่timestamptz
ข้อมูลเช่นnow()
เข้าไปในสนามว่ามันจะเป็นครั้งแรกถูกแปลงเป็นเขตเฉพาะ (อย่างใดอย่างหนึ่งอย่างชัดเจนด้วยat time zone
หรือโดยการแปลงเขตเวลาเซสชั่น) และข้อมูลเขตเวลาจะถูกยกเลิก มันไม่ได้หมายถึงเวลาที่แน่นอนอีกต่อไป นี่คือเหตุผลที่คุณไม่ต้องการจัดเก็บการประทับเวลาtimestamp
และโดยปกติแล้วจะใช้งานtimestamptz
- ภาพยนตร์อาจได้รับการเผยแพร่ในเวลา 18.00 น. ตามวันที่กำหนดในทุกเขตเวลานั่นเป็นกรณีการใช้งาน
หากคุณเท่านั้นที่เคยทำงานในเขตเวลาเดียวที่คุณอาจได้รับไปด้วย timestamp
(MIS) การแปลงกลับtimestamptz
เป็นฉลาดพอที่จะรับมือกับ DST และจะใช้การประทับเวลาเพื่อจุดประสงค์ในการแปลงให้อยู่ในเขตเวลาปัจจุบัน นี่คือตัวอย่างสำหรับ GMT / BST:
select '2011-03-27 00:59:00.0+00'::timestamptz::timestamp::timestamptz
, '2011-03-27 01:00:00.0+00'::timestamptz::timestamp::timestamptz;
/*
|timestamptz |timestamptz |
|:---------------------|:---------------------|
|2011-03-27 00:59:00+00|2011-03-27 02:00:00+01|
*/
DBFiddle
แต่ให้สังเกตพฤติกรรมที่ทำให้สับสนดังนี้
set timezone to 0;
values(1, '1970-01-01 00:00:00+00'::timestamp::timestamptz)
, (2, '1970-01-01 00:00:00+02'::timestamp::timestamptz);
/*
|column1|column2 |
|------:|:---------------------|
| 1|1970-01-01 00:00:00+00|
| 2|1970-01-01 00:00:00+00|
*/
DBFiddle
นี่เป็นเพราะ :
PostgreSQL ไม่เคยตรวจสอบเนื้อหาของสตริงตัวอักษรก่อนที่จะกำหนดประเภทของมันและดังนั้นจะถือว่าทั้ง [... ] เป็นเวลาที่ไม่มีเขตเวลา เพื่อให้แน่ใจว่าตัวอักษรได้รับการปฏิบัติเสมือนเป็นการประทับเวลาที่มีเขตเวลาให้เป็นประเภทที่ชัดเจนที่ถูกต้อง ... ในตัวอักษรที่ได้รับการพิจารณาให้เป็นการประทับเวลาโดยไม่มีเขตเวลา PostgreSQL จะไม่สนใจตัวบ่งชี้เขตเวลาใด ๆ