【问题标题】:Are unix timestamps the best way to store timestamps?unix 时间戳是存储时间戳的最佳方式吗?
【发布时间】:2008-10-07 14:29:21
【问题描述】:

我总是对所有事情都使用 unix 时间戳,但我想知道是否有更好的方法。

您使用什么来存储时间戳,为什么?

【问题讨论】:

    标签: timestamp


    【解决方案1】:

    无论您选择如何存储时间戳,重要的是要避免区域解释问题和时间偏移问题。无论区域如何,Unix 时间戳的解释都是相同的,并且无论时区如何,都是从同一时间点计算出来的——这些都是好事。

    谨防将时间戳存储为不明确的字符串,例如 01/02/2008,因为这可能会被解释为 2008 年 1 月 2 日或 2008 年 2 月 1 日,具体取决于区域设置。

    在存储小时/分钟/秒时,重要的是要知道指定了“哪个”小时/分钟/秒。您可以通过包含时区信息来做到这一点(Unix 时间戳不需要,因为它被假定为 UTC)。

    但是,请注意,Unix 时间戳不能唯一地表示某些时间瞬间:当 UTC 有闰秒时,Unix 时间戳不会改变,因此 UTC 时间为 23:59:60 和次日 00:00:00具有相同的 Unix 表示。因此,如果您确实需要一秒或更佳的分辨率,请考虑另一种格式。

    如果您更喜欢比 Unix 时间戳更易于阅读的存储格式,请考虑使用ISO 8601

    一种有助于保持直截了当的技术是将日期存储为 UTC,并且仅在向用户显示日期时应用时区或 DST 偏移量。

    【讨论】:

    • 确切地说,您不能忽略时区。单个时间戳意味着仅基于时区的不同时刻。也不能假设仅使用偏移量就可以解决此问题,因为偏移量会发生变化,例如使用 DST。 derickrethans.nl/storing-date-time-in-database.html
    【解决方案2】:

    如果您要存储日志文件,请看在 pete 的份上,使其具有人类可读性和词汇可排序性。

    例如 2008-10-07 09:47:02。

    【讨论】:

    • 7 年了...人类可读性很好,我完全赞成,但这个例子中的日期是模棱两可的。如果您真的需要知道某事何时发生,您需要时区信息,因此请使用 2008-10-07T09:47:02Z 之类的信息,以便获得人类可读性和精确的时间点。
    • 这不是模棱两可的。没有????-??-??日期格式不是yyyy-mm-dd,即除了“T”之外的ISO-8601。
    • 我喜欢你花了一分钟点击发布按钮
    【解决方案3】:

    32 bit Unix timestamps will overflow in a few years (January 2038),所以这可能是一个考虑因素。我通常在 SQL 中使用 DATETIME 格式,即 YYYY-MM-DD HH:MM:SS,时间为 24 小时制。我尝试以相同的格式输出到文件,只是为了让我的生活更轻松。

    【讨论】:

    • 2038 for 32bit 但现在大多数系统都是 64bit
    • 已修复和链接。 @mgb - 是的,尽管我认为嵌入式系统最麻烦。
    • 是的。对于在 2038 年运行 32 位操作系统的人来说,这只会是一个问题。恕我直言——这将是应得的。即使现在大多数系统都使用 64 位操作系统。 64 位操作系统的到期日期是 292,277,026,596 日,星期日,292,277,026,596。
    • @Andre:64 位操作系统与它几乎没有关系:这取决于您如何存储时间戳。如果您使用的是 32 位 int(例如,在 C 中,大多数 64 位系统上的 int 类型),那么您仍然会遇到问题。同样,大多数 32 位系统都可以轻松使用 64 位 int,并且可以不受此影响。您必须查看如何将数据存储在任何存储介质中,无论是 RAM、磁盘、网络传输等...
    • +1 提醒我们考虑 32 位 int 时间戳。对于大约 64 位系统的 cmets,几乎为 -1。 :D
    【解决方案4】:

    您需要存储什么时代以及达到什么分辨率? 如果您需要微秒,或者石器时代的日期 time_t 可能不是最好的。 对于一般商业用途,它非常好(假设是 64 位)

    【讨论】:

    • 您确实需要长期计算诸如天文事件(日食等)的日期/时间,这个系统(儒略日)开始于公元前 5000 年左右
    【解决方案5】:

    这取决于您需要时间戳的用途。

    unix 时间戳不能表示 2008-12-31T23:59:59Z 之后 1 秒的时间。 如果您使用 unix 时间戳执行 '2009-01-01T09:00:00' - '2008-12-31T09:00:00' ,则结果不正确:这两个日期之间会有闰秒并且它们是分开的86401 秒(不是 86400,因为 unix 时间戳会告诉你)。

    除此之外以及其他响应者所说的,是的——unix时间戳是要走的路:)

    【讨论】:

      【解决方案6】:

      时间戳不是数据库的好主意,因为它们不考虑夏令时或当前本地时间。在 MySQL 上,最好将其存储为时间,然后使用 MySQL date and time functions 检索您想要的部分,或与其他日期进行比较。

      【讨论】:

        【解决方案7】:

        timeval-style (time_t + microseconds) 如果我需要亚秒级精度,否则只需 time_t。您可以使用 64 位整数值来存储 time_t * 1000000 + usec,并且您可以防溢出超过 +/- 292,000 年。

        【讨论】:

          【解决方案8】:

          UNIX 时间戳 32 位问题对于输入 2038+ 未来日期的用户来说似乎很烦人。

          要么使用 MySQL 的 DATETIME 序列,要么将日期存储为 BIGINT(8) 无符号(最大值:18 quintillion)或 FLOAT,以便您可以输入大数字。然后你不能使用例如 PHP 的 date() 函数,因为它只允许整数作为参数(受 32 位系统限制)。

          我找到的解决方案是使用PHP 5.2.0函数。 Here's the DateTime PHP solution.

          无需更改 UNIX_TIMESTAMP 格式。只要您将 BIGINT(8) 未签名作为您的 MySQL 时间戳存储。您将不再受 32 位系统的限制。

          【讨论】:

          • 您答案中的链接需要登录。
          【解决方案9】:

          时间戳基本上是:

          • 一个独特的时间点

          由于时间点具有无限的分辨率,选择时间戳格式的重要事项是:它是否具有足够的分辨率?

          对于我拥有的大多数应用程序,纳秒就足够了。所以到目前为止,Java Timestamp 的分辨率对我来说是正确的。

          【讨论】:

            猜你喜欢
            • 2015-05-11
            • 2012-07-15
            • 2017-03-03
            • 2017-01-18
            • 2017-06-14
            • 2013-03-23
            • 2021-02-12
            • 1970-01-01
            相关资源
            最近更新 更多