对于符合 ISO8601 的日期时间
2004-10-19 10:23:54+02
是否可以将带有+02
偏移量的值反映在存储的列值中,并在选择时保留?
从我阅读文档的相应部分来看, Postgres 的默认行为是转换为 UTC,此时原始偏移量将丢失。这当然是我所看到的。
数据是通过无法添加任何特殊 tz 转换的 ORM 访问的,因此我真的需要简单地存储具有原始偏移量的日期时间,并在选择时反映该值。
对于任何想告诉我这是同一时间的人来说,保存这个值对这个数据很重要。
对于符合 ISO8601 的日期时间
2004-10-19 10:23:54+02
是否可以将带有+02
偏移量的值反映在存储的列值中,并在选择时保留?
从我阅读文档的相应部分来看, Postgres 的默认行为是转换为 UTC,此时原始偏移量将丢失。这当然是我所看到的。
数据是通过无法添加任何特殊 tz 转换的 ORM 访问的,因此我真的需要简单地存储具有原始偏移量的日期时间,并在选择时反映该值。
对于任何想告诉我这是同一时间的人来说,保存这个值对这个数据很重要。
正如您自己已经弄清楚的那样,时区根本不使用 Postgres 日期/时间类型保存,甚至使用timestamptz
. 它的角色分别只是输入修饰符或输出修饰符。仅保存值(时间点)。此相关答案中有大量详细信息:
因此,如果您想保留输入字符串的那部分,您必须将其从字符串中提取并自己保存。我会使用如下表格:
CREATE TABLE tstz
...
, ts timestamp -- without time zone
, tz text
)
tz
,being text
, 可以保存数字偏移量以及时区缩写或时区名称。
困难在于根据解析器遵循的所有各种规则并以不易破坏的方式提取时区部分。与其编写自己的过程,不如让解析器完成这项工作。考虑这个演示:
WITH ts_literals (tstz) AS (
VALUES ('2013-11-28 23:09:11.761166+03'::text)
,('2013-11-28 23:09:11.761166 CET')
,('2013-11-28 23:09:11.761166 America/New_York')
)
SELECT tstz
,tstz::timestamp AS ts
,right(tstz, -1 * length(tstz::timestamp::text)) AS tz
FROM ts_literals;
使用或不使用T
介于日期和时间之间的情况。关键逻辑在这里:
right(tstz, -1 * length(tstz::timestamp::text)) AS tz
在修剪解析器识别为日期/时间组件的长度后,获取时间戳字符串的剩余部分。正如您所说,这取决于输入:
经过验证的 ISO8601 字符串
Java 开发人员可以将Joda Time与Jadira UserTypePersistentDateTimeAndZone
结合使用。例子:
@Basic(optional = false)
@Columns(columns = { @Column(name = "modificationtime"),
@Column(name = "modificationtime_zone") })
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTimeAndZone")
@Index(name = "payment_modificationtime_idx")
private DateTime modificationTime = null;
在此示例中,DateTime
信息位于 2 列中:
modificationtime timestamp without time zone
将时间戳存储在 UTC 时区modificationtime_zone varchar(255)
将时区 ID 存储为字符串(例如America/Caracas
)虽然 Joda Time 和 Jadira(以及 Hibernate)是 Java 特有的(并且是事实上的方法),但上述构造 RDBMS 列以存储时间戳和时区的方法可以应用于任何编程语言。
本机 postgres日期/时间数据类型不会为您保留输入时区。如果您需要在数据库中查询它作为时间戳并显示原始信息,您将不得不以某种方式存储这两条信息。
我打算建议您的 ORM 可以定义自定义充气/放气方法来处理魔术,但显然它不能。您应该指出您正在使用哪个 ORM。
您可以让 ORM 在数据库中存储/检索字符串,并使用 Postgres 中的触发器将其转换为存储在另一列中的时间戳,该列在执行数据库端查询时使用。如果您有许多包含此类数据的表,那可能会有点笨拙。
如果你真的想要数据库中单个列中的数据,你可以在 Postgres 中定义一个复合类型,尽管你的 ORM 可能无法处理它们。