使用unix_timestamp()后,MySQL时间戳数学行为有所不同

时间:2013-02-26 16:52:17

标签: mysql

我正在试图找出MySQL在时间戳的数学运算期间正在做什么。

产生问题的图片:

enter image description here

你会在左边看到我有两个时间戳,开始和结束,我需要找到从开始到结束的持续时间,所以我只是这样做:

结束 - 开始

我得到了一些非常奇怪的结果。您可以看到持续时间仅为3小时我得到的结果表明该数量的2到3倍。

当我首先转换为UTC时,数学运算正常。

有人能解释一下SQL在左边的时间戳上做了什么吗?我一直以为所有时间戳都是UTC的印象,这就是为什么像min,max,less等等没有转换的原因。

谢谢!

代码:

select  
    min(timestamp) start, 
    max(timestamp) end, 
    max(timestamp) - min(timestamp) start_to_end, 
    unix_timestamp(min(timestamp)) startUTC, 
    unix_timestamp(max(timestamp)) endUTC,
    unix_timestamp(max(timestamp)) - unix_timestamp(min(timestamp)) start_to_end_UTC
from post_snapshots group by permalink;

3 个答案:

答案 0 :(得分:1)

这不是DATETIMETIMESTAMP或时区问题。

MySQL通过将每个值转换为数字来处理日期时间作为减法(或其他数学运算)的操作数,但它不是秒数,而只是日期时间数字串在一起。以您的数据为例:

2013-02-19 16:49:21变为20130219164921

2013-02-19 19:07:31变为20130219190731

这两个数字之间的差异是...... 25810,这是您在减法操作中看到的值。正如你所指出的那样,这不是几秒钟内的结果。它真的没有多大意义。

相比之下,TIMESTAMPDIFF()(或者像你所做的那样预转换为Unix时间戳)实际上是使用适合时间的数学运算来实现差异的,如果你正在寻找差异而不是排序的重要性:

SELECT TIMESTAMPDIFF(SECOND, '2013-02-19 16:49:21', '2013-02-19 19:07:31')
>>> 8290

答案 1 :(得分:1)

这些示例与时区转换无关 - 当您直接从另一个日期中减去一个日期时,MySQL会从所有现有日期部分生成一个整数,然后进行数学运算。例如,此查询:

select now()+1;

返回(这是'2013-02-26 14:38:31'+ 1):

+----------------+
| now()+1        |
+----------------+
| 20130226143832 |
+----------------+

所以“2013-02-19 16:49:21”和“2013-02-19 19:07:31”的区别原来是:

20130219190731 - 20130219164921 = 25810

获得此减法的正确方法是将日期转换为时间戳(与您一样)或使用TIMESTAMPDIFF(SECOND, start_date, end_date),这将返回8290.

答案 2 :(得分:0)

如果你不能在mysql中减去日期/日期时间会发生什么。对于所有数学运算,mysql时间戳数据类型的行为类似于datetime数据类型。 你可以使用

  select  
    TIMESTAMPDIFF(SECOND,min(timestamp),max(timestamp))
  from post_snapshots group by permalink;