Считать n дней, пропуская указанные даты - PullRequest
1 голос
/ 27 марта 2012

Я пытаюсь выяснить лучший способ подсчитать, какой день будет 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 ]

1 голос
/ 28 марта 2012

Вы можете написать сохраненную функцию -

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 с выходными для почтовой службы.

1 голос
/ 27 марта 2012

«Лучший» способ, конечно, зависит от контекста вашей реализации.

(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).карта.(Это решает проблему границ того, как определить, каким должен быть последний день на карте.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...