【发布时间】:2019-01-24 23:44:59
【问题描述】:
我在其他项目中遇到过这个问题,但现在我们正在使用 Django / Python 与 Vue.js 和 PostgreSQL。
我们模型中几乎每个“日期”字段都是真正的日期,而不是日期时间。业务用户不关心时间部分,实际上存储任何此类值都是误导性的。一个很好的例子是税率的生效日期。从用户的角度来看,它在指定日期的午夜生效。
如果我们将它存储为 Django DateTimeField 或 DateField,它需要一个时间部分。它可能是 0000h,但该值对业务没有意义,因为他们永远不需要查看或比较任何与时间部分的内容。如果我们想存储一个真实的日期时间,将其作为 UTC 放入数据库,然后通过自动时区转换以本地时间显示给用户,那么 Django 的功能非常棒。但我们没有。如果生效日期是 2019 年 3 月 1 日,则无论用户的时区如何,它都应显示为这样。如果日期存储为日期时间 (2019, 3, 1, 0, 0, 0) 并由温哥华的某人输入,则它将显示为多伦多的另一个用户的下一个日历日。绝对不是我们想要的。我们可以通过将时间部分设置为 1200 小时来解决这个问题,但真的吗?
在使用 SQL 或直接访问模式的工具(例如 BI 工具)时,我们也存在潜在问题,具体取决于数据库中的内部表示。我们如何知道哪个时区适用于日期时间值?
因此,我们正在考虑使用 ISO 8601 格式 (YYYY-MM-DD) 的 Django CharField。它将正确排序,可以轻松比较(或直接在某些工具中,如 SQL),并且如果客户愿意使用该标准,则无需重新格式化即可显示。如果我们需要进行日期运算,我们可以使用 Python 标准库 datetime 和 calendar 来转换字符串。无论如何,我们都需要使用它们来捕获 SQL 注入攻击。
我们还需要通过 Datepicker 处理日期输入,在存储之前转换为 ISO 8601 字符串,并在显示以供编辑时再次返回。
这似乎是代表业务需求的更好方式,并且它消除了任何时区转换问题。
当然有很多关于日期时间和时区处理的评论,但我还没有发现有人采用这种方法来存储真实日期。我错过了一个重要的“陷阱”吗?我们在项目中处于足够早的阶段,我们可以采取任何一种方式,所以我希望在重构成为一项重要工作之前确认这将起作用。
【问题讨论】:
-
"then display it to users in their local time through the automatic time zone conversion."这是不准确的。 Django 不进行任何自动 tz 转换。它仅将数据库中的日期时间存储为 UTC(或您想要使用的任何 tz),如果您想在原始 tz 中显示该日期时间,因为它存储在数据库中或根据最终用户进行任何转换,这取决于您。因此,生效日期 - 2019 年 3 月 1 日 不会自动转换。 -
前段时间我回答了一个问题,我解释了 django 中的时区是如何工作的,您可能会发现它很有帮助:- stackoverflow.com/a/48028119/1925257。此外,还有一个
DateField,不需要时间。
标签: django string date datetime iso8601