首页 > 解决方案 > ISO 8601 字符串而不是日期时间

问题描述

我在其他项目中遇到过这个问题,但现在我们正在使用 Django / Python 与 Vue.js 和 PostgreSQL。

几乎我们模型中的每个“日期”字段都是真正的日期,而不是日期时间。业务用户不关心时间部分,实际上存储任何此类值都是误导性的。一个很好的例子是税率的生效日期。从用户的角度来看,它在指定日期的午夜生效。

如果我们将其存储为 Django DateTimeField 或 DateField,它需要一个时间部分。它可能是 0000h,但该值对业务没有意义,因为他们永远不需要查看或比较任何与时间部分的内容。如果我们想存储一个真实的日期时间,将其作为 UTC 放入数据库,然后通过自动时区转换以本地时间显示给用户,那么 Django 的功能非常棒。但我们没有。如果生效日期是 2019 年 3 月 1 日,则无论用户的时区如何,它都应显示为这样。如果日期存储为日期时间 (2019, 3, 1, 0, 0, 0) 并由温哥华的某人输入,则它将显示为多伦多的另一个用户的下一个日历日。绝对不是我们想要的。我们可以通过将时间部分设置为 1200 小时来解决它,但真的吗?

当使用 SQL 或直接访问模式的工具(例如 BI 工具)时,我们也有潜在的问题,具体取决于数据库中的内部表示。我们如何知道哪个时区适用于 datetime 值?

因此,我们正在考虑使用 ISO 8601 格式 (YYYY-MM-DD) 的 Django CharField。它将正确排序,可以轻松比较(或直接在某些工具中,如 SQL),并且如果客户愿意使用该标准,则无需重新格式化即可显示。如果我们需要进行日期运算,我们可以使用 Python 标准库 datetime 和 calendar 来转换字符串。无论如何,我们都需要使用它们来捕获 SQL 注入攻击。

我们还需要通过 Datepicker 处理日期输入,在存储之前转换为 ISO 8601 字符串,并在显示以进行编辑时再次返回。

它似乎是代表业务需求的更好方式,并且它摆脱了任何时区转换问题。

关于日期时间和时区处理当然有很多评论,但我还没有发现有人采用这种方法来存储真实日期。我错过了一个重要的“陷阱”吗?我们在项目中已经足够早了,我们可以采取任何一种方式,所以我希望在重构成为一项重要工作之前确认这将起作用。

标签: djangostringdatedatetimeiso8601

解决方案


您是否考虑过使用DateField

这将只存储日期部分而不是时间。


推荐阅读