【问题标题】:Daylight saving time abolition - am I saving datetimes correctly?取消夏令时 - 我是否正确保存日期时间?
【发布时间】:2019-08-22 16:44:48
【问题描述】:

我目前正在开发一个 PHP/mySQL Web 应用程序,我们在其中将日期存储为 UNSIGNED INT(10) 列中的 unix 时间戳。每当我们需要在 Web 视图中显示日期时,我们都会获取该数字并使用 moment.js 对其进行解析。

虽然我的一位同事对这种解决任务的方式存有疑问(他更喜欢将日期存储为“YYYY-MM-DD hh:mm:ss”VARCHARs),但到目前为止我们的问题为零。

我最近读到欧盟正在推进废除夏令时。根据我存储日期的特定方式,这会以任何方式影响我的 web 应用吗?

【问题讨论】:

  • 为什么将日期时间存储为 varchar?有一个专用的日期时间类型。

标签: javascript database database-design dst


【解决方案1】:

一些事情:

  • MySQL 具有内置的日期和时间标准数据类型。它们是DATEDATETIMETIMESTAMP。您可以阅读更多关于它们的信息in the MySQL documentation here。您应该从这些类型中选择一种,而不是存储整数或 varchars。

  • 这与 DST 的关系在很大程度上取决于上下文。没有一种正确的方法可以存储所有日期和时间。任何关于“始终存储在 UTC”的建议都是短视的,应该不鼓励。相反,请考虑日期和时间所代表的上下文。详细说明:

    • Unix 时间戳始终基于 UTC,因此与 DST 或时区的其他影响没有任何关系。当某事发生在现在或过去发生时,这是表示时间戳的好方法。在 MySQL 中,TIMESTAMP 类型与此概念非常吻合。

    • 如果您要存储未来某个事件的预定时间,则 本地 日期和时间在上下文中更为重要。在 MySQL 中,您可以将其存储在 DATETIME 类型中。如果您正在处理多个时区,那么您还需要该事件的时区标识符(例如America/New_York),您可以将其存储在VARCHAR 中。在这种情况下,DST 非常依赖与该时区相关的基础规则。 MySQL 具有像 CONVERT_TZ 这样的函数,可以理解这些标识符并使​​用底层操作系统时区数据或其自己的时区表来了解 DST 是否有效。

    • 如果您使用的是完整日期,例如出生日期、周年日期、雇用日期或按给定工作日汇总数据,则需要将其保留为不带时间或时区的日期。这就像你在看纸质日历上的日期方块一样。 MySQL 对此有 DATE 类型。在这种情况下,DST 不相关,除了确定某个时间点属于哪个日期。例如,当我们询问“今天”是哪一天时,我们也会考虑时间和时区,包括 DST - 但一旦我们声明“2019 年 4 月 4 日”,那么所有这些信息都会被删除。

  • 您问题的最后一部分涉及如何实施基础时区数据,以及在欧盟废除 DST 时如何更新这些数据。为此,我将向您推荐this answer,它解释了 IANA 时区数据库并直接解决了当前的欧盟问题。

【讨论】:

    【解决方案2】:

    我会出来说不,这应该没关系。我不是专家,但我也将日期存储为 UNIX 时间戳,如果您要生成 10 位时间戳,则类似于:

    getSecondsSinceEpoch = ((date) => Math.floor(date.getTime()/1000));
    

    (或任何依赖Date.prototype.getTime()),那么您将存储一个不关心时区的通用日期,这很好,因为如果用户从不同的时区登录,您不会返回 varchars是基于他们过去的位置。这同样适用于夏令时更改其时区的时钟(或在被废除后未能这样做)。

    为了获得用户当前位置的正确人类可读字符串,Javascript 依赖于 timezoneOffset,它不是日期对象的一部分,而是回答“这个浏览器现在距离伦敦多少时区”的问题?” (除了以分钟而不是小时为单位,并且在考虑夏令时之后。)据推测,用户的设备将意识到这一变化,他们的浏览器也会如此,并且您的脚本将能够采取相应的行动。 (如果他们的设备使用了错误的时区,那么在他们解决之前,您的应用不会是唯一一个行为不端的应用。)

    正如我所说,我不是这方面的专家,所以我可能已经说服自己关于 Javascript 处理日期的方式不正确,但就我目前的理解而言,我认为你的解决方案应该没问题。我希望如果我弄错了,其他书呆子会立即加入并让我们都知道。

    【讨论】:

    • 迟到总比没有好,我添加了关于 getTimezoneOffset 的说明。
    • 这并不能真正回答所提出的问题。将来,请尝试特别关注所询问的内容。此外,您的解释中有几件事混为一谈,但要指出的主要一点是,偏移量与特定时间点距 UTC(协调世界时)的分钟数有关,而不是与伦敦以外的时区计数有关。请记住 - 伦敦也有夏令时。他们称之为英国夏令时 (BST)。
    • 谢谢,马特。您能否澄清关于偏移的“特定时间点”位,并让我们知道我还混淆了什么?
    • .getTimezoneOffset() 是一个适用于 Date 对象的特定实例的函数 - 它表示一个唯一的时间点(基于 UTC)。因此,返回的偏移量是针对 那个 时间点的。 new Date().getTimezoneOffset() 给出 当前 时区偏移量。它没有说明过去的偏移量或将来的偏移量。这适用于夏令时转换或与标准时间更改相关的转换。请参阅the timezone tag wiki 中的“时区!= 偏移量”。
    • 至于我是否回答了这个问题,我不得不不同意你的看法。 Claudio 写道:“我最近读到欧盟正在推进废除夏令时。这会根据我存储日期的特定方式以任何方式影响我的 web 应用程序吗?”,对此我给出了明确的“不”然后试图解释我的推理(并澄清我不是 100% 确定。)我不确定什么是更“真实”的答案。
    猜你喜欢
    • 1970-01-01
    • 2020-04-29
    • 2013-05-25
    • 2012-04-07
    • 2012-07-09
    • 2015-07-09
    • 2019-08-31
    • 2017-08-28
    • 2022-01-20
    相关资源
    最近更新 更多