计算n天,跳过指定的日期

时间:2012-03-27 13:07:12

标签: mysql date

我正在试图找出计算从现在起n天的哪一天的最佳方式,但不计算某一组日期(邮政服务假期/星期日)。

For example, 5 days from December 20th:
Dec 21st = 1
Dec 22nd = 2
Dec 23rd = skipped (Sunday)
Dec 24th = 3
Dec 25th = skipped (Xmas)
Dec 26th = 4
Dec 27th = 5

我的设置将是一个包含开始日期的表格,一个用于确定每种记录类型应计算的天数的表格,以及一个用于列出应从计算中排除的天数的表格(星期日不包含在此列表中)。

2 个答案:

答案 0 :(得分:1)

当然,“最佳”方式取决于您的实施环境。

(1)如果你的开始日期很少,你可以沿着你现在所遵循的路线前进。

for each startingDate
    counter = 0
    advanceDate = startingDate
    do while counter < nOfBusinessDays
        advanceDate  = advanceDate.addDays(1) # whatever your environment provides for date arithmetic
        if advanceDate is found in tableOfSundays # see (a) below
            continue
        if advanceDate is found in tableOfHolidays
            continue
        counter++
    end do while
    # advanceDate is nOfBusinessDays later than startingDate
end for each

(a)如果您的日期算术包提供星期几功能,您可以将其用于星期日测试。

(2)如果您需要评估很多开始日期,并且/或者您将反复计算相同的日期加天数,则可以预先计算工作日地图。该地图将涵盖表格中最早开始日期与最新开始日期之间的时间跨度,加上计算的最大工作日数以及周日和节假日的间隔时间。以升序日期顺序将地图实现为普通数组。然后从开始日算起工作日只是数组索引的问题。

(3)您可以使用方法(1)开始实现混合解决方案,然后在方法(2)地图中缓存答案。 (这解决了如何弄清楚地图中最新日期应该是什么的边界问题。)

答案 1 :(得分:1)

您可以编写存储函数 -

CREATE FUNCTION find_a_day(start_date DATE, n INT)
  RETURNS date
BEGIN
  DECLARE i INT DEFAULT 1;
  DECLARE end_date DATE DEFAULT start_date;
  WHILE i < n DO
    SET end_date = end_date + INTERVAL 1 DAY;

    -- Create 'holidays' table!
    SELECT COUNT(*) INTO @holydays FROM holidays WHERE date = end_date;

    IF @holydays = 0 AND DAYOFWEEK(end_date) <> 1 THEN
      SET i = i + 1;
    END IF;
  END WHILE;

  RETURN end_date;
END

创建一个包含邮政服务假期的holydays表。