我将 AWS RDS 用于带有 PGAdmin 的 PostgreSQL 11 数据库。我存储每一行的创建日期,now()::timestamp
用于存储没有时区的日期和时间。问题是存储的时间永远不是我想要的值(UTC+05:30
)。
如果我在 RDS 中设置参数timezone
,UTC
则存储的时间比印度时间晚 5:30 小时,但如果我设置 UTC+05:30,它存储的时间要么晚 11 小时,要么多 1 小时,这在随机行中随机发生。我没有改变任何其他东西,只是这个timezone
参数。
我搜索了很多,但没有找到任何类似的答案。
tl;博士
TIMESTAMP WITHOUT TIME ZONE
,为数据类型定义列TIMESTAMP WITH TIME ZONE
。AT TIME ZONE 'Asia/Kolkata'
. (但最好将该区域调整留给您的应用程序代码而不是您的 SQL。)TIMESTAMP WITHOUT TIME ZONE
定义列时使用了错误的数据类型。
TIMESTAMP WITHOUT TIME ZONE
数据类型不能代表时刻。这种类型故意缺少时区或从 UTC 偏移的上下文。所以你有一个日期和一个时间,比如明年 1 月 23 日的中午。但我们无法知道您是指日本东京的中午、法国图卢兹的中午,还是美国俄亥俄州托莱多的中午,所有这些时刻相隔几个小时。
到达 type 的列时,将忽略与输入一起传递的任何时区或偏移信息
TIMESTAMP WITHOUT TIME ZONE
。TIMESTAMP WITH TIME ZONE
该
TIMESTAMP WITH TIME ZONE
类型可以跟踪时刻,时间轴上的特定点。与日期和时间一起传递的任何时区或偏移信息都用于调整为 UTC。然后丢弃区域/偏移量。因此,如果您关心原始区域/偏移量,则需要将其显式存储在额外的列中。
检索
TIMESTAMP WITH TIME ZONE
值时,该值将始终采用 UTC(零时分秒的偏移量)。但是,请注意带有将某些默认时区或偏移量注入检索到的值的反特性的工具、中间件或驱动程序。这会造成该区域/偏移量已被存储的错觉,而实际上 Postgres 总是以数据类型的 UTC 值存储TIMESTAMP WITH TIME ZONE
。PgAdmin是具有这种不幸的反功能的工具之一。我建议始终将会话的默认区域设置为 UTC,以便在存储时查看检索到的值。
调整时区
我建议你学习在 UTC 作为一名程序员思考和工作。您在编程中的大部分业务逻辑都应该使用 UTC。调整到仅用于向用户展示或业务逻辑需要的时区。所以这意味着在大多数情况下,您应该只在您的应用程序代码中而不是在您的 SQL 和数据库管理工具中调整时区。
AT TIME ZONE
功能但是,如果您坚持使用 SQL 调整时区,请使用该
AT TIME ZONE
功能。您提到了比 UTC 提前五个半小时的偏移量,
+05:30
. 我假设您的意思是在印度的时间。总是更喜欢实时时区名称而不是特定的偏移量。政客们经常改变他们管辖范围内使用的偏移量。所以硬编码偏移量可能会导致错误的结果。让您的 Postgres 安装中的tzdata文件保持最新,然后让 Postgres 确定适用于该特定时刻的指定时区的偏移量。
各种日期时间数据类型
我为 Java 程序员制作的这张图表在这里也可能有用,可以更好地理解 SQL 标准定义的各种数据类型。
我认为您应该将其用作默认值:
然后 PostgreSQL 将获取当前时间点并将其格式化为印度当时显示的时间戳。