长话短说;博士。使用 microtime(false) 并将结果以百万分之一秒的形式存储在 MySQL bigint 中。否则你必须学习所有关于浮点运算的知识,这是一个大毛球。
PHP microtime 函数从一个系统调用获取 Unix 时间戳(当前约为十六进制 50eb7c00 或十进制 1,357,609,984),并从另一个系统调用获取微秒时间。然后它将它们变成一个字符串。然后,如果您使用 (true) 调用它,它会将该数字转换为 64 位 IEEE 745 浮点数,PHP 将其称为float
.
截至目前,您需要小数点左侧十个十进制数字来存储整数 UNIX 时间戳。这种情况一直持续到公元 2280 年左右,届时您的后代将开始需要 11 位数字。您需要小数点右侧的六位数字来存储微秒。
您不会获得完全微秒的精度。大多数系统保持其亚秒级系统时钟的分辨率在 1-33 毫秒范围内。它依赖于系统。
MySQL 版本 5.6.4 及更高版本允许您指定DATETIME(6)
列,它将保存微秒分辨率的日期和时间。如果您使用这样的 MySQL 版本,那绝对是正确的选择。
5.6.4版本之前,需要使用MySQLDOUBLE
(IEEE 754 64 位浮点)来存储这些数字。 MySQLFLOAT
(IEEE 754 32 位浮点)尾数中没有足够的位来完全准确地存储当前的 UNIX 时间(以秒为单位)。
为什么要存储这些时间戳?你希望做吗
WHERE table.timestamp = 1357609984.100000
或类似的查询来查找特定项目?如果您在处理链中的任何位置使用浮点数或双精度数(也就是说,即使您使用microtime(true)
哪怕只有一次)。他们因无法平等而臭名昭著,即使你认为他们应该平等。相反,你需要使用这样的东西。这0.001
ì 在数值加工贸易中称为“epsilon”。
WHERE table.timestamp BETWEEN 1357609984.100000 - 0.001
AND 1357609984.100000 + 0.001
或类似的东西。如果将这些时间戳存储为小数或百万分之一秒,则不会出现此问题bigint
column.
IEEE 64 位浮点有 53 位尾数——精度。当前 UNIX 纪元时间戳(自 1970 年 1 月 1 日 00:00Z 起的秒数)乘以一百万使用 51 位。因此,如果我们关心低位,则 DOUBLE 中没有太多额外的精度。另一方面,精度在几个世纪内都不会耗尽。
使用 int64(BIGINT),您远不会耗尽精度。如果我实际上只是为了在 MySQL 中排序而存储微秒时间戳,我会选择DATETIME(6)
因为我可以免费得到很多日期算术。如果我正在做一个内存中的高容量应用程序,我会使用 int64。