7ca*_*ect 5 postgresql timestamp timezone
例如,我有一个带有时间戳的表:
2018-04-05 06:00:00 +01
2018-04-05 06:00:00 +00
2018-04-05 06:00:00 -01
2018-04-05 04:00:00 -01
Run Code Online (Sandbox Code Playgroud)
我想要获得的条目是......
BETWEEN 2018-04-05 06:00:00+01 AND 2018-04-05 07:00:00+01
Run Code Online (Sandbox Code Playgroud)
所以我的输出是:
2018-04-05 06:00:00 +01
2018-04-05 04:00:00 -01
Run Code Online (Sandbox Code Playgroud)
操作员会BETWEEN
自动处理时区差异并为我提供所需的输出吗?
这才有效:
\n\nSELECT *, ts AT TIME ZONE \'-01\' -- see below about \'-1\' vs \'+1\'\nFROM (\n VALUES \n (1, timestamptz \'2018-04-05 06:00:00 +01\')\n , (2, \'2018-04-05 06:00:00 +00\')\n , (3, \'2018-04-05 06:00:00 -01\')\n , (4, \'2018-04-05 04:00:00 -01\')\n ) t(id, ts)\nWHERE ts BETWEEN \'2018-04-05 06:00:00+01\' -- coerced to timestamptz\n AND \'2018-04-05 07:00:00+01\'; -- derived from context!\n
Run Code Online (Sandbox Code Playgroud)\n\n但请注意这里的几个陷阱和潜在的误解!
\n\nSQL构造BETWEEN ... AND
(严格来说不是一个函数;实际上更像是一个运算符)与时区无关。这将是对事物运作方式的误解。
请注意两种不同的数据类型timestamp
( timestamp without time zone
) 和timestamptz
( timestamp with time zone
)。看:
特别是,文字中的时区偏移量timestamptz
仅用作值的输入/输出修饰符,并且根本不存储。仅内部存储相应的 UTC 时间。看:
请注意由于 POSIX 和 SQL 标准之间的分歧,时间戳文字和时区说明符(翻转符号)之间存在奇怪的语法差异:
\n\n您显示的输出(具有不同的时区偏移量)不能通过简单地返回timestamptz
值来实现:
\n\n\nRun Code Online (Sandbox Code Playgroud)\n2018-04-05 06:00:00 +01\n2018-04-05 04:00:00 -01\n
timestamptz
值始终根据会话的设置显示。timezone
要获取显示的字符串(针对不同的时区),您必须保留输入的时区偏移量并使用它来格式化输出。(或将完整的输入文字存储为text
)
最后,请注意“2018-04-05 04:00:00 -01”也通过了测试,因为它与“2018-04-05 06:00:00+01”的值完全相同',只是格式不同(同一时间点,针对不同时区显示)。\n因此,在您的示例中,三行通过了测试,而不仅仅是两行。timestamptz
如果您现在头晕目眩,请考虑这个演示:\n
\n\n\n\n\nRun Code Online (Sandbox Code Playgroud)\n\nWITH tbl AS (\n SELECT *\n , split_part(tstz_string, \' \', 3) AS tz_string\n , tstz_string::timestamptz AS tstz\n FROM (\n VALUES \n (1, \'2018-04-05 06:00:00 +01\')\n , (2, \'2018-04-05 06:00:00 +00\')\n , (3, \'2018-04-05 06:00:00 -01\')\n , (4, \'2018-04-05 04:00:00 -01\')\n ) t(id, tstz_string)\n )\nSELECT *\n , to_char(tz_string::numeric * -1, \'SG00\') AS tz_posix\n , tstz AT TIME ZONE (tz_string::numeric * -1)::text AS ts_at_org_tz\n , (tstz AT TIME ZONE (tz_string::numeric * -1)::text)::text || \' \' || tz_string AS tstz_org\n , (tstz AT TIME ZONE (tz_string::numeric * -1)::text)::text || \' \' || tz_string \n = tstz_string AS strings_equal\nFROM tbl;\n
\nid | tstz_string | tz_string | tsz | tz_posix | ts_at_org_tz | ts_at_org_tz | tstz_org | strings_equal\n-: | :---------------------- | :-------- | :-------------------- | :----- | :------------------ | :---------------------- | :------------\n 1 | 2018-04-05 06:00:00 +01 | +01 | 2018-04-05 06:00:00+01 | -01 | 2018-04-05 06:00:00 | 2018-04-05 06:00:00 +01 | t \n 2 | 2018-04-05 06:00:00 +00 | +00 | 2018-04-05 07:00:00+01 | +00 | 2018-04-05 06:00:00 | 2018-04-05 06:00:00 +00 | t \n 3 | 2018-04-05 06:00:00 -01 | -01 | 2018-04-05 08:00:00+01 | +01 | 2018-04-05 06:00:00 | 2018-04-05 06:00:00 -01 | t \n 4 | 2018-04-05 04:00:00 -01 | -01 | 2018-04-05 06:00:00+01 | +01 | 2018-04-05 04:00:00 | 2018-04-05 04:00:00 -01 | t\n\n
db<>在这里摆弄
\n 归档时间: |
|
查看次数: |
3274 次 |
最近记录: |