mysql timediff 休息 12 小时

Posted

技术标签:

【中文标题】mysql timediff 休息 12 小时【英文标题】:mysql timediff is 12 hours off 【发布时间】:2015-10-07 15:37:28 【问题描述】:

我正试图找出我的时钟查询中的一个错误。打卡时间是下午 12 点,打卡时间是下午 12 点 30 分。我在 mysql 中使用 timediff 计算差异。我将突破时间和突破时间传递给 timediff 函数。它返回正确的分钟,但它也返回 -12 小时。当我在 timediff 函数中交换 breakin 和 breakout 时,它会返回一个正的 12 小时和正确的分钟。

我想有人可能想查看该查询。警告:它又大又丑。 查询:

SELECT CONCAT(pe.first, ' ', pe.last) AS Name,
               U.EmpID AS 'Empl ID',
               DATE_FORMAT(U.`time`, '%m-%d-%Y') AS 'Punch Date',
               DATE_FORMAT(U.`time`, '%W') AS 'Weekday',
               TIME_FORMAT(SEC_TO_TIME(SUM(U.delta)), '%H:%i') AS 'Time Worked',
               TIME_FORMAT(
                  TIMEDIFF(
                     (SELECT PunchDateTime
                        FROM timeclock_punchlog tp
                       WHERE     PunchEvent = 'breakout'
                             AND DATE(tp.PunchDateTime) = DATE(U.time)
                             AND tp.EmpID = U.EmpID), 
                     (SELECT PunchDateTime
                        FROM timeclock_punchlog tp
                       WHERE     PunchEvent = 'breakin'
                             AND DATE(tp.PunchDateTime) = DATE(U.time)
                             AND tp.EmpID = U.EmpID)),
                  '%h hrs, %i min.')
                  AS Lunch
                FROM ((SELECT `enter`.EmpID,
                           `enter`.PunchDateTime AS `time`,
                           DATE_FORMAT(`enter`.PunchDateTime, '%m-%d-%Y')
                              AS 'Punch Date',
                           TIMESTAMPDIFF(SECOND,
                                         `enter`.PunchDateTime,
                                         '2003-05-01 00:00:00')
                              AS `delta`
                      FROM timeclock_punchlog AS `enter`
                     WHERE `enter`.`In-Out` = 1)
                   UNION
                   (SELECT `leave`.EmpID,
                           `leave`.PunchDateTime AS `time`,
                           DATE_FORMAT(`leave`.PunchDateTime, '%m-%d-%Y')
                              AS 'Punch Date',
                           -TIMESTAMPDIFF(SECOND,
                                          `leave`.PunchDateTime,
                                          '2003-05-01 00:00:00')
                              AS `delta`
                      FROM timeclock_punchlog AS `leave`
                     WHERE `leave`.`In-Out` = 0)) AS U
               LEFT JOIN prempl pe ON u.EmpID = pe.prempl
        WHERE DATE(U.`time`) >= "2015-10-05"
        AND DATE(U.`time`) <= "2015-10-07"
        AND U.EmpID = 0349
        GROUP BY date(U.`time`), EmpID
        ORDER BY U.EmpID, U.`time` ASC

这是一个SQL Fiddle,它通过一个简单的查询重现了该问题。

insert into times values 
    ('12:30 pm','12:00 pm'),
    ('12:00 pm','12:30 pm');

select time_format(timediff(start,end),'%h hrs, %i min.') from times

结果:

12 hrs, 30 min.
-12 hrs, 30 min.

这是一个使用 datetime 类型的 sql fiddle 并产生相同的结果。 http://sqlfiddle.com/#!9/9fb73/1

【问题讨论】:

很难看出这不是一个错误。 所以你说这是mysql timediff函数的一个bug? @dmikester1 cloud 请检查时区设置;这可能是个问题。 @akm 在 mysql 中?有没有办法在 mysql 中运行查询之前设置时区?我不知道为什么这很重要。 @dmikester1 时区可能有问题;如果您的 SQL 客户端代码和服务器代码位于两台不同的机器上,那么在连接时您可能会遇到这样的问题,我认为您的情况并非如此。现在看看你的 SQL 小提琴,我看到你正在使用 char 数据类型来存储 time 你在其他表中做同样的事情吗? 【参考方案1】:

问题在于格式化时间;看看差异是否为负,你会遇到这样的麻烦。

time_format 也有一些限制,我建议阅读有关它的 MySQL 文档。

根据上次通信;我假设您使用的是 datetime 数据类型,那么以下查询将起作用。

CREATE TABLE `times` (
  `PunchID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `breakout` datetime NOT NULL,
  `breakin` datetime NOT NULL,
  PRIMARY KEY (`PunchID`)
);

insert into `times` 
values (1,'2015-10-06 12:00:00', '2015-10-06 12:30:00');

选择查询(注意格式字符串h改为H

select time_format(timediff(breakin,breakout),'%H hrs, %i min.') from times;

一切正常。

如果您不确定哪一列可能比其他列具有更大的价值,请提供一些建议,执行 timediff 并对其进行格式化可以给您带来奇怪的结果,更好地在这种情况下使用 UNIX_TIMESTAMP() 并处理整数数学。

MySQL date and time functions. 上的文档

【讨论】:

【参考方案2】:

您不能直接将'12:30 pm' 之类的时间字符串输入 MySQL。 am / pm 部分将始终被忽略。尝试改用 24 小时格式。

【讨论】:

实际上@dmikester1 使用的是char 数据类型而不是time,这就是MySQL 允许这样的馈送并导致错误结果的原因。 不,我正在为我的表使用日期时间类型。创建小提琴的人将其作为字符输入。 添加了一个使用日期时间类型的小提琴,并且没有 am/pm 来操作。它产生相同的结果

以上是关于mysql timediff 休息 12 小时的主要内容,如果未能解决你的问题,请参考以下文章

不同行中的值之间的差异,基于 timediff

mysql 计算两个日期的时间差函数小时分钟格式

MYSQL 使用 GROUP BY 到 SUM timediff 得到总打开时间

MYSQL日期时间总结

mysql TIMEDIFF 和 TIMESTAMPDIFF的使用(问题记录)

从所有行中获取 MySQL 中的 TIMEDIFF()