การใช้เวลาปัจจุบันใน UTC เป็นค่าเริ่มต้นใน PostgreSQL


172

ฉันมีคอลัมน์TIMESTAMP WITHOUT TIME ZONEประเภทและต้องการให้มีค่าเริ่มต้นเป็นเวลาปัจจุบันใน UTC การรับเวลาปัจจุบันใน UTC เป็นเรื่องง่าย:

postgres=# select now() at time zone 'utc';
          timezone          
----------------------------
 2013-05-17 12:52:51.337466
(1 row)

เช่นเดียวกับการใช้การประทับเวลาปัจจุบันสำหรับคอลัมน์:

postgres=# create temporary table test(id int, ts timestamp without time zone default current_timestamp);
CREATE TABLE
postgres=# insert into test values (1) returning ts;
             ts             
----------------------------
 2013-05-17 14:54:33.072725
(1 row)

แต่นั่นใช้เวลาท้องถิ่น การพยายามบังคับให้ UTC ส่งผลให้เกิดข้อผิดพลาดทางไวยากรณ์:

postgres=# create temporary table test(id int, ts timestamp without time zone default now() at time zone 'utc');
ERROR:  syntax error at or near "at"
LINE 1: ...int, ts timestamp without time zone default now() at time zo...

คำตอบ:


297

ไม่จำเป็นต้องใช้ฟังก์ชั่น เพียงใส่วงเล็บล้อมรอบนิพจน์เริ่มต้น:

create temporary table test(
    id int, 
    ts timestamp without time zone default (now() at time zone 'utc')
);

2
ฉันสามารถดู funciton เช่น now_utc (ก) จริงๆส่องเมื่อเขียนคำสั่ง
misaxi

สิ่งนี้สามารถใช้งานได้เมื่อเวลาย้อนกลับไปหนึ่งชั่วโมง - ตอนนี้ () ส่งคืนการประทับเวลาที่รู้ค่าชดเชยจาก UTC
Clay Lenhart

1
FWIW วิ่งแบบสอบถามนี้ใน PostgreSQL 11.5: ล้มเหลวด้วย:ALTER TABLE testcase_result ADD COLUMN date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT (NOW() AT TIME ZONE "UTC") NOT NULL; ตรวจสอบให้แน่ใจว่าเป็นตัวพิมพ์เล็กทั้งหมด ERROR: column "UTC" does not exist'utc'
code_dredd

2
การแก้ไข: 'utc'สตริงต้องเป็นแบบเครื่องหมายคำพูดเดียวไม่ใช่แบบเครื่องหมายคำพูดคู่
code_dredd



16

เกี่ยวกับอะไร

now()::timestamp

หากการประทับเวลาอื่นของคุณไม่มีเขตเวลาการส่งสัญญาณนี้จะให้ประเภทการจับคู่ "การประทับเวลาที่ไม่มีเขตเวลา" สำหรับเวลาปัจจุบัน

ฉันต้องการอ่านสิ่งที่คนอื่นคิดเกี่ยวกับตัวเลือกนั้น ฉันยังไม่เชื่อมั่นในความเข้าใจของฉันเกี่ยวกับสิ่งนี้ "กับ / ไม่" เขตเวลา

แก้ไข: การเพิ่มความคิดเห็น Michael Ekoka ของที่นี่เพราะมันชัดเจนประเด็นสำคัญ:

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


มันเป็นกลอุบายที่น่าสนใจ แต่อาจนำไปสู่ความสับสนเว้นแต่คุณจะรับรู้ถึงพฤติกรรมนี้ คำตอบที่ได้รับการยอมรับนั้นชัดเจนในการดำเนินการและผลลัพธ์ที่ต้องการ เหมือนกันกับฟังก์ชั่น แต่ฉันก็ยังอยู่ห่างจากฟังก์ชั่นใน DBs ....
Frank V

ในตัวเลือกของฉันมันจะสร้างช่วงเวลาท้องถิ่นลงใน db
VelikiiNehochuha

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

@MichaelEkoka ฉันได้เพิ่มความคิดเห็นของคุณเป็นคำตอบ - โปรดไปข้างหน้าและแก้ไขหากคุณต้องการ คุณอธิบายได้ชัดเจนมาก ขอบคุณ!
Risadinha

คำเตือน : ฟิลด์การประทับเวลาพร้อมเขตเวลาไม่ได้จัดเก็บเขตเวลาตรงกันข้ามกับสมมติฐานที่สมเหตุสมผล ดูลิงค์ด้านล่างและค้นหาหน้า UTC บนอินพุตการประทับเวลาที่มีโซนเวลาจะแปลงค่าที่ได้รับเป็น utc และเก็บค่านั้นโดยไม่มีข้อมูลโซนเวลาหรือค่าที่ไม่ได้ตั้งค่าไว้ บนเอาต์พุตค่า utc ที่เก็บไว้จะถูกแปลงเป็นเวลาท้องถิ่นโดยใช้โซนเวลาของไคลเอ็นต์หากมี ประเภทนี้คือทั้งหมดที่เกี่ยวกับการแปลงค่า ณ เวลาที่สืบค้น คุณควรทดสอบสิ่งนี้โดยการจัดเก็บจากโซนเวลาหนึ่งและเลือกจากโซนอื่น postgresql.org/docs/11/datatype-datetime.html
Tom

7

เหล่านี้เป็นโซลูชั่นที่เทียบเท่า 2:

(ในรหัสต่อไปคุณควรทดแทน'UTC'สำหรับโซนและnow()สำหรับการประทับเวลา )

  1. timestamp AT TIME ZONE zone - SQL-standard-conforming
  2. timezone(zone, timestamp) - สามารถอ่านได้ง่ายขึ้น

เขตเวลาของฟังก์ชั่น (เขตเวลาประทับ) จะเทียบเท่ากับเขตเวลาประทับของการสร้างตามมาตรฐาน SQL ที่เขตเวลาเขตเวลา


คำอธิบาย:

  • เขตสามารถระบุเป็นสตริงข้อความ (เช่น, 'UTC') หรือเป็นช่วงเวลา (เช่น, INTERVAL '-08:00') - นี่คือรายการของเขตเวลาที่มีอยู่ทั้งหมด
  • การประทับเวลาสามารถเป็นค่าของการประทับเวลาชนิดใดก็ได้
  • now()ส่งคืนค่าการประทับเวลาชนิด(สิ่งที่เราต้องการ) โดยแนบโซนเวลาเริ่มต้นของฐานข้อมูลของคุณ (เช่น2018-11-11T12:07:22.3+05:00)
  • timezone('UTC', now())เปลี่ยนเวลาปัจจุบันของเรา (ประเภทการประทับเวลากับโซนเวลา ) ลงในเทียบเท่า timezonless UTCใน
    เช่นจะกลับมาSELECT timestamp with time zone '2020-03-16 15:00:00-05' AT TIME ZONE 'UTC'2020-03-16T20:00:00Z

เอกสาร: เขตเวลา ()


1
ขอบคุณสำหรับการสรุปสิ่งเหล่านี้ ฉันใช้เวอร์ชันตัวพิมพ์เล็กat timezone 'utc'และไม่สามารถใช้กับการตั้งค่า PostgreSQL ของฉัน การใช้ตัวอักษรตัวพิมพ์ใหญ่แก้ไขปัญหา
Geradlus_RU

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