63

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

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

4

9 回答 9

100

无论您选择存储时间戳,重要的是要避免区域解释问题和时间偏移问题。无论区域如何,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 偏移量。

于 2008-10-07T14:50:28.357 回答
31

如果您要存储日志文件,请出于对 pete 的喜爱,使其具有人类可读性和词汇可排序性。

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

于 2008-10-07T14:48:15.490 回答
18

32 位 Unix 时间戳将在几年后(2038 年 1 月)溢出,所以这可能是一个考虑因素。我通常在 SQL 中使用 DATETIME 格式,即 YYYY-MM-DD HH:MM:SS,时间为 24 小时制。我尝试以相同的格式输出到文件,只是为了让我的生活更轻松。

于 2008-10-07T14:32:49.140 回答
7

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

于 2008-10-07T14:33:09.280 回答
4

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

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

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

于 2008-10-07T14:43:25.453 回答
4

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

于 2008-10-07T14:44:45.200 回答
2

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

于 2008-10-07T14:34:10.697 回答
1

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

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

我找到的解决方案是使用PHP 5.2.0函数。这是 DateTime PHP 解决方案

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

于 2010-10-12T16:06:10.963 回答
0

时间戳基本上是:

  • 一个明显的时间点

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

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

于 2008-10-07T14:36:52.253 回答