Вам нужно будет создать таблицу для хранения значений даты и времени.
CREATE TABLE calendarhours (caldaytime DATETIME);
Затем вам нужно будет создать хранимую процедуру для циклического прохождения двух дат и вставить значения даты и времени для расписаний в таблицу.
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `timesheetdays`(startdate DATETIME, enddate DATETIME)
BEGIN
DECLARE tempdate DATETIME;
DELETE FROM `calendarhours`;
-- set the temp date to 9am of the start date
SET tempdate = DATE_ADD(DATE(startdate), INTERVAL '0 9' DAY_HOUR);
-- while the temp date is less than or equal to the end date, insert the date
-- into the temp table
WHILE ( tempdate <= enddate ) DO
BEGIN
-- insert temp date into temp table
INSERT INTO `calendarhours` (caldaytime) VALUES (tempdate);
-- increment temp date by an hour
SET tempdate = DATE_ADD(tempdate, INTERVAL '0 1' DAY_HOUR);
-- if the temp date is greater than 5 PM (17:00) then increment to the next day
IF TIMEDIFF(tempdate, DATE_ADD(DATE(tempdate), INTERVAL '0 17' DAY_HOUR)) > 0 THEN
BEGIN
-- increment to the next day
SET tempdate = DATE_ADD(DATE(tempdate), INTERVAL '1 9' DAY_HOUR);
-- for business purposes, if the day is a Saturday or a Sunday increment
-- until we reach Monday
WHILE ( DAYNAME(tempdate) = 'Saturday' OR DAYNAME(tempdate) = 'Sunday' ) DO
BEGIN
SET tempdate = DATE_ADD(DATE(tempdate), INTERVAL '1 9' DAY_HOUR);
END;
END WHILE;
END;
END IF;
END;
END WHILE;
-- return all the inserted date and times
SELECT * FROM calendarhours ORDER BY caldaytime;
END
Затем эта процедура будет проходить через две даты, начиная с 9 часов утра каждый день и заканчивая в 5 часов вечера каждый день (17:00). Когда время достигает 18:00, процедура увеличивается на следующий день и начинается снова в 9:00.
Если вы работаете со стандартным расписанием рабочей недели, то если день равен субботе или воскресенью, он будет увеличиваться до достижения понедельника.
Чтобы проверить это, я использовал следующие утверждения:
CALL `timesheetdays`(NOW(), DATE_ADD(DATE(NOW()), INTERVAL '5 0' DAY_HOUR));
SELECT * FROM `calendarhours`;
Это проверяет процедуру с сегодняшнего дня до 5 дней с сегодняшнего дня и показывает количество часов по мере необходимости. Первый оператор добавляет записи в таблицу, а затем возвращает записи, второй оператор возвращает записи из таблицы.