ISO 8601 字符串而不是日期时间

ISO 8601 string instead of datetime

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

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

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

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

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

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

这似乎是一种更好的表示业务需求的方式,而且它消除了任何时区转换问题。

肯定有很多关于日期时间和时区处理的评论,但我还没有发现任何人采用这种方法来存储真实日期。我错过了一个重要的 'gotcha' 吗?我们在项目中处于足够早的阶段,我们可以采用任何一种方式,所以我希望在重构成为一项大工作之前确认这会起作用。

您是否考虑过使用 DateField

这只会存储日期部分,不会存储时间。