ใน postgres, timestamp with time zoneสามารถย่อเป็นtimestamptzและเป็นtimestamp without time zone timestampฉันจะใช้ชื่อประเภทสั้นลงเพื่อความเรียบง่าย
การรับ Unix timestamp จาก postgres timestamptzlike now()นั้นง่ายอย่างที่คุณพูดเพียง:
select extract(epoch from now());
ที่จริงสิ่งที่คุณจำเป็นต้องรู้เกี่ยวกับการรับเวลาที่แน่นอนจากสิ่งที่ประเภทรวมทั้งtimestamptznow()
สิ่งที่ซับซ้อนเมื่อคุณมี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 จะไม่สนใจตัวบ่งชี้เขตเวลาใด ๆ