Postgres DATE_TRUNC正在移动时间戳



我正在使用一个名为architect的python包,它有助于在Django模型中使用Postgres分区。我已经为每个月建立了分区表。但在检查限制中,我看到被截断的日期正在被更改。例如

DATE_TRUNC('month','2020-09-12 15:23:00+05:45')给出2020-09-01 05:45:00+05:45

因此,检查约束变为

CONSTRAINT "transactionservice_transaction_y2020m09_TransactionDate_check" CHECK ("TransactionDate" >= '2020-09-01 05:45:00+05:45'::timestamp with time zone AND "TransactionDate" < '2020-10-01 05:45:00+05:45'::timestamp with time zone)
)

这导致来自2020-9-1 02:03:33的事务在2020-08的事务表中,这不是我想要的。

我从pgadmin中尝试了这个,结果是2020-09-01 00:00:00+05:45,这是我所不同的。

但是从架构师包执行的sql代码导致了上述转变。

这是来自architect的代码中添加了检查约束的部分。

def _get_date_definitions(self):
"""
Returns definitions for date partition subtype.
"""
patterns = {
'day': '"y"YYYY"d"DDD',
'week': '"y"IYYY"w"IW',
'month': '"y"YYYY"m"MM',
'year': '"y"YYYY',
}
try:
pattern = patterns[self.constraint]
except KeyError:
raise PartitionConstraintError(
model=self.model.__name__,
dialect=self.dialect,
current=self.constraint,
allowed=patterns.keys())
return {
'formatters': {'pattern': pattern},
'variables': [
"match := DATE_TRUNC('{constraint}', NEW.{{column}});",
"tablename := '{{parent_table}}_' || TO_CHAR(NEW.{{column}}, '{pattern}');",
"checks := '{{column}} >= ''' || match || ''' AND {{column}} < ''' || (match + INTERVAL '1 {constraint}') || '''';"
]
}

有人能向我解释一下移位的原因吗

观察2020-09-01 05:45:00+05:452020-09-01 00:00:00Z在不同时区是同一时间点。一个在+05:45,一个在UTC。您的应用程序可能将2020-09-01 00:00:00解释为UTC,然后将其更改为应用程序的时区。

如果该列是不带时区的timestamp,则date_trunc将生成不带区域的时间戳。我的时区是-0700。

select date_trunc('month', timestamp '2020-09-12 15:23:00+05:45')
2020-09-01 00:00:00
select date_trunc('month', timestamptz '2020-09-12 15:23:00+05:45')
2020-09-01 00:00:00-07

CCD_ 11是一个不明确的时间点。您的应用程序可能会将其解释为UTC或应用程序的时区+05:45。它似乎将其解释为UTC,然后将其转换为应用程序的时间。UTC中的2020-09-01 00:00:002020-09-01 05:45:00+05:45

Django关于时区的文档似乎证实了这一点。

当启用对时区的支持时,Django会在数据库中存储UTC格式的日期时间信息,在内部使用可识别时区的日期时间对象,并以模板和表单将其转换为最终用户的时区。

我不熟悉Django,不知道该如何解决这个问题。故障排除部分有"3。now.date((是昨天!(或明天("关于将日期时间转换为可能相关的日期的陷阱。

最新更新