it-swarm.asia

كيف أحصل على الطابع الزمني الحالي ليونيكس من PostgreSQL؟

الطابع الزمني Unix هو عدد الثواني منذ منتصف الليل UTC 1 يناير 1970.

كيف أحصل على الطابع الزمني الصحيح لليونيكس من PostgreSQL؟

عند المقارنة بـ currenttimestamp.com و timestamp.1e5b.de لا أحصل على الوقت المتوقع من PostgreSQL:

يؤدي هذا إلى إرجاع الطابع الزمني الصحيح:

SELECT extract(Epoch from now());

في حين أن هذا لا:

SELECT extract(Epoch from now() at time zone 'utc');

أعيش في المنطقة الزمنية UTC +02. ما هي الطريقة الصحيحة للحصول على الطابع الزمني الحالي لليونكس من PostgreSQL؟

هذا يعيد المنطقة الزمنية والوقت الصحيحة:

SELECT now();
              now
-------------------------------
 2011-05-18 10:34:10.820464+02

مقارنة أخرى:

select now(), 
extract(Epoch from now()), 
extract(Epoch from now() at time zone 'utc');
              now              |    date_part     |    date_part
-------------------------------+------------------+------------------
 2011-05-18 10:38:16.439332+02 | 1305707896.43933 | 1305700696.43933
(1 row)

Unix timestamp from the web sites:
1305707967
99
Jonas

في postgres ، يمكن اختصار timestamp with time zone كـ timestamptz ، و timestamp without time zone كـ timestamp. سأستخدم أسماء أقصر من أجل البساطة.

إن الحصول على الطابع الزمني لـ Unix من postgres timestamptz مثل now() أمر بسيط ، كما تقول ، فقط:

select extract(Epoch from now());

هذا كل ما تحتاج لمعرفته حول الحصول على الوقت المطلق من أي شيء من النوع timestamptz ، بما في ذلك now().

تصبح الأمور معقدة فقط عندما يكون لديك حقل timestamp.

عندما تضع timestamptz بيانات مثل now() في هذا الحقل ، سيتم تحويلها أولاً إلى منطقة زمنية معينة (إما صراحةً باستخدام at time zone أو عن طريق التحويل إلى المنطقة الزمنية للجلسة) و يتم تجاهل معلومات المنطقة الزمنية . لم يعد يشير إلى وقت مطلق. هذا هو السبب في أنك لا تريد عادةً تخزين الطوابع الزمنية كـ timestamp وعادة ما تستخدم timestamptz - ربما يتم إصدار الفيلم في الساعة 6 مساءً في تاريخ معين في كل منطقة زمنية ، هذا هو نوع حالة الاستخدام.

إذا كنت تعمل في منطقة زمنية واحدة فقط ، فقد تتخلص من (الخطأ) باستخدام timestamp. التحويل إلى timestamptz ذكي بما يكفي للتعامل مع التوقيت الصيفي ، ويُفترض أن تكون الطوابع الزمنية ، لأغراض التحويل ، في المنطقة الزمنية الحالية. في ما يلي مثال لـ 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 بصمت أي إشارة إلى المنطقة الزمنية

90
Jack says try topanswers.xyz
SELECT extract(Epoch from now() at time zone 'utc');

لا يُرجع الطابع الزمني الصحيح لأن تحويل المنطقة الزمنية postgres يتخلص من معلومات المنطقة الزمنية من النتيجة:

9.9.3. AT TIME ZONE

بناء الجملة: الطابع الزمني بدون منطقة زمنية AT TIME ZONE zone
المرتجعات: الطابع الزمني مع المنطقة الزمنية
تعامل مع طابع زمني معين بدون منطقة زمنية كما هو موجود في المنطقة الزمنية المحددة

بناء الجملة: الطابع الزمني مع المنطقة الزمنية AT TIME ZONE zone
المرتجعات: الطابع الزمني بدون منطقة زمنية
تحويل طابع زمني معين مع المنطقة الزمنية إلى المنطقة الزمنية الجديدة ، بدون تحديد المنطقة الزمنية

بعد ذلك ، يظهر المقتطف في الطابع الزمني بدون منطقة زمنية ويعتبره توقيتًا محليًا (على الرغم من أنه بالفعل في الواقع).

الطريقة الصحيحة ستكون:

select now(),
       extract(Epoch from now()),                                          -- correct
       extract(Epoch from now() at time zone 'utc'),                       -- incorrect
       extract(Epoch from now() at time zone 'utc' at time zone 'utc');    -- correct

          now                  |    date_part     |    date_part     |    date_part
-------------------------------+------------------+------------------+------------------
 2014-10-14 10:19:23.726908+02 | 1413274763.72691 | 1413267563.72691 | 1413274763.72691
(1 row)

في السطر الأخير الأول at time zone يقوم بالتحويل ، والثاني يعين منطقة زمنية جديدة للنتيجة.

23
axil