PostgreSQL应用程序中的不同时区

时间:2018-02-23 21:22:17

标签: database postgresql

我们有一个服务于许多分发中心的系统。配送中心是该国任何地方的物理空间。一个客户可能有多个配送中心。现在我们正在扩展到更多的地方,我们将不得不面对不同时区的问题。同一个客户也可能拥有不同时区的中心。

可以使用我们在客户中心的系统创建和保存许多事件(包括日期和小时)。同一客户端中不同时区的理想行为如下:

考虑在时区A,中午发生的事件。如果时区B中另一个配送中心的主管检查此事件,他应该看到该事件的日期和时间与最初创建事件的时区有关(包括DST更改,如果存在)。 这是因为重要的是,事件是在事件时区中午创建的。对于主管而言,无论事件何时创建,都是在他的时区中的下午2点。

我们使用PostgreSQL作为我们的数据库,我发现存在两种不同的类型来保存时间戳。 TIMESTAMPTIMESTAMPTZ。我们所有的数据库都只使用TIMESTAMP类型。

可能(或不会)发生的另一种情况是配送中心在地理位置上发生变化的情况。这可能会影响其时区的变化。

我做了一些研究,发现更“正确”的方法(至少看起来似乎)是保存DISTRIBUTION_CENTER表中每个中心的时区。在我们的数据库中将所有类型从TIMESTAMP更改为TIMESTAMPTZ,并在保存时间戳的事件的每个插入中,我们应该使用创建事件的中心的时区来保存事件时区的偏移量( TIMESTAMPTZ只保存时区的偏移量,而不是时区本身的偏移量。

我并不完全相信这是处理不同时区的正确(或最佳)方法。因为我从来没有这样做过,所以我不能说。

如果我必须遵循这种方法,我将不得不在数据库中将所有列类型从TIMESTAMP更改为TIMESTAMPTZ。还必须重新创建以某种方式依赖于该列的所有视图,因为我们将更改列类型。我还必须更改处理该列的所有查询,以便使用AT TIMEZONE应用中心时区。

数据库现在已经设置了America/Sao_Paulo时区,并且在更改TIMESTAMPTZ的列类型时,我的担心最终导致出错。此更改是否可能会破坏数据一致性?我应该首先更改列类型还是更改UTC的数据库时区?

我描述的解决方案是最好的方法吗?

这种方法是否也能正确处理DST更改?

额外信息:我们的服务器使用java(jersey)。

1 个答案:

答案 0 :(得分:0)

阅读Basil的理解这些概念的令人印象深刻的答案。

你一定要切换到timestamp with time zone,这实际上是绝对时间戳(略微违反了SQL标准的意图)。

您想要改变的一件事是,如果记录它的中心的时区发生变化,事件的时区应该改变。如果没有,您将需要保留中心的时区历史记录,或者(更好地)在创建每个事件时存储时区。