【问题标题】:Time difference between dates, including business hour and excluding holidays日期之间的时差,包括营业时间,不包括节假日
【发布时间】:2012-10-05 20:53:44
【问题描述】:

如何计算两个日期之间的时间差,考虑:

  • 仅限周一至周五
  • 上午 9 点到下午 5:30 之间的时间;
  • 不包括节假日。

例子:

  • d1 = 2012-10-05 17:00:00
  • d2 = 2012-14-09 12:00:00

计算步骤:

  • 2012-10-05 = 00:30:00
  • 2012-10-06 = 00:00:00
  • 2012-10-07 = 00:00:00
  • 2012-10-08 = 07:30:00
  • 2012-10-09 = 04:00:00

ddiff(d2,d1) = 12:00:00

我知道如何仅使用周一至周五 as described here 来做到这一点。我说的是 MySQL。

【问题讨论】:

  • 这个问题很相似。也许你可以把它当作灵感。 stackoverflow.com/questions/593898/sql-datediff-advanced-usage
  • 这将需要行级操作(光标),并且您将需要一个假期表。
  • @foampile 。 . .这不需要游标。日历表是识别节假日的首选方式,比仅包含节假日的表更好。
  • 是的,您可以通过获取两个日期之间的行数以及 IS_WORK_DAY=1 乘以 8 加上第一个和最后一个日期的营业时间来使用日历表。 . 但是这涉及到一个日历表,而不是一个假日表......就个人而言,为了简单和代码清洁,我会选择一个简单的光标,但这是一个偏好问题
  • 就个人而言,我会在应用层而不是 SQL 中进行此计算。想到 Perl

标签: mysql


【解决方案1】:

我想出了一个相对简单的解决方案来计算完整 临时日期的时差。但是,使用 mysql 计算开始和结束日期的时间差有点麻烦。我将它们包含在我的解决方案中,但有一些假设。

无论如何,这是 sql

SET @startdate:='2012-12-24 17:00:00';
SET @enddate:='2013-01-02 12:00:00';

SELECT
TIME_TO_SEC(TIMEDIFF(CONCAT(DATE(@startdate),' 17:30:00'), @startdate))/3600 as startday_time,
TIME_TO_SEC(TIMEDIFF(@enddate, CONCAT(DATE(@enddate),' 9:00:00')))/3600 as endday_time,
SUM(daily_hours) as otherdays_time from
(
    SELECT 7.5 as daily_hours, id, DATE_ADD(DATE(@startdate),INTERVAL id-1 DAY) as idate from numbers
) dates
LEFT JOIN holidays on DATE(dates.idate) = DATE(holidays.date)
WHERE
idate BETWEEN @startdate AND @enddate
AND holidays.date IS NULL
AND DAYOFWEEK(idate) <> 7 AND DAYOFWEEK(idate) <> 1;

这里的sqlfiddle: http://sqlfiddle.com/#!2/ff3f3/1/2

要获得有效的临时日期,我们需要两个表 - 一个列出所有假日日期的 holidays 表和一个包含一系列整数的 numbers 表,这对于加入对以获得连续的非常有用一系列日期(没有间隔)。

注意:在 sqlfiddle 中,我仅将 numbers 表填充到 12 个以涵盖我的示例中使用的日期 - 根据您的日期范围,它可能需要填充到更高的数字'会一起工作的。

对于开始日时间和结束日时间,我做了以下假设:

  • 开始日期和结束日期都是应计入总时间的有效日期
  • 开始日期的时间在午餐和 17.30 之间
  • 结束日期的时间在午餐和 17.30 之间

如果这些假设是错误的,那么您将进入严重的条件领域(有很多 if),最好在 php(或其他)中这样做。

注意:出于说明目的,我未添加时间(以小时为单位)。

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 2018-04-04
    • 2019-05-11
    • 2020-12-08
    • 2019-07-14
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多