在Django / Postgres中存储壁钟日期时间

时间:2019-03-11 12:08:04

标签: django postgresql timezone

我想为Django中的事件保存将来的挂钟日期时间(我的时区字符串单独存储)。

我不能简单地使用DateTimeField,因为它强制执行timestamp with time zone并总是节省当前时区的时间。它不处理DST或当前日期与实际事件日期之间可能发生的时区更改。

我可以使用以下任一选项:

  • 选择任何时区以存储时间戳,并始终将其丢掉,然后再在Python中应用实际时区。
  • 将时间戳分为DateFieldTimeField
  • 将日期时间存储为字符串。
  • 将日期时间存储为timestamp without time zone的自定义字段。

但是它使查询更加困难并且看起来很奇怪。

我有没有更好的选择?这个用例似乎很常见,所以我想有更好的方法吗?

编辑:我的用例:

比方说,我的用户想要预订2019年12月20日10:00的约会,当前是2019年3月10日。我知道此用户的时区(它以字符串形式存储,例如“ US / Eastern”)。

如果我假设EST从2019年11月3日开始,那么我能做的最好的就是将时间戳存储到2019-12-20 15:00:00+00:00(或2019-12-20 10:00-05:00。我不希望这样做是因为,

  • 我不知道我的tzdata是否具有将来日期时间的正确信息
  • 即使当前确实如此,我也不知道美国/东部时区是否会发生任何意外变化,如果不是美国,情况会变得更糟。无法保证将来的DST更改。
  • 如果用户移到不同的时区,则在考虑DST的同时我必须重新计算每个约会。
  • 如果在重新计算期间tzdata发生了变化,请不要考虑这一点。

我希望将将来的日期存储为朴素的datetime +时区字符串(例如“ US / Eastern”),并且(几乎)永远不会构造一周以上的任何可感知tz的日期时间。 Django + postgres当前强迫我使用timestamp with time zone,这对日志和过去的事件非常有用,但是它具有固定的偏移量(甚至没有时区名称),因此不适合将来的挂钟日期时间。

对于这个用例,假设我不在乎时间的模棱两可:没有太多用户希望在02:00 AM预订。

1 个答案:

答案 0 :(得分:1)

我看到一些可能的解决方案:

  1. 设置USE_TZ = FalseTIME_ZONE = 'UTC'并使用日历时间。不会进行任何转换,因此从本质上讲,您只是存储日历时间并将其恢复为原始日期时间。主要问题是此设置是全局设置,对于很多用途而言都不是一个很好的设置(例如auto_now)。

  2. 如上所述,但是设置USE_TZ = True。只要您以UTC表示日历时间,就不会有任何不愉快的转换。这里的问题是您将了解日期时间,因此您必须小心忽略或删除任何地方的时区。

  3. 使用单独的DATE_FIELDTIME_FIELD。根据您要运行的查询类型,这可能是一个好的解决方案,也可能不是一个好的解决方案。

  4. 使用timestamp without time zone创建您自己的字段。 (或者也许是already exists?)

请注意,此问题与过去和将来无关。这是关于要使用固定时间而非日历(或挂钟)时间的问题。您提出的观点肯定是反对使用时间来代表日历时间的。