我正在使用 MySQL 程序来获取商店营业时间内的营业日期。
我的商店有不同的送货/取货时间(delivery_type)。此外,我使用整数参数(偏移量)来增加当前时间,以防商店真的很忙。只能在当天考虑偏移量。
营业时间在表 *shop_hours* 中定义为与星期几 (1-7) 匹配的一条记录。为了增加一些灵活性,我有一个单独的表 *shop_hours_special* 用于特殊日期。此表会否决 shop_hours 中定义的任何开/关时间。*shop_hours_special* 定义为一年中的某一天。
我的问题:
- 调用 nextDate(2, 9999999);
这将返回 2012-12-16(即今天的 UTC+1),但偏移参数非常高,以至于它应该推到下一个开放日期,例如 2012-12-17 星期一。
- 调用 nextDate(1,0);
如果店铺今天有营业时间,但还没到营业时间,则返回下一个营业日,但确实应该返回今天的日期。
有人可以帮忙吗,我做错了什么?
PHP函数:
public function get_next_open_date($delivery_type, $offset = 0) {
$sql = 'CALL nextDate('.$delivery_type.','.$offset.');';
$date = $this->app['db']->fetchAssoc($sql);
return date('Y-m-d', strtotime($date['final_date']));
}
MySQL程序:
DROP PROCEDURE IF EXISTS `nextDate`;
DELIMITER $$
CREATE PROCEDURE `nextDate`(IN dType TINYINT(3), IN dOffset INT)
BEGIN
DECLARE CURTIME TIME;
DECLARE final_date DATE;
DECLARE match_found, closed_day BOOLEAN;
DECLARE dYear, dWeek, dayYear, dayWeek, contor INT;
SET contor = 0;
SET match_found = TRUE;
SET dayYear = DAYOFYEAR(NOW());
SET dayWeek = WEEKDAY(NOW()) + 1;
SET dYear = -1;
SET dWeek = -1;
SET CURTIME = ADDTIME(TIME(NOW()),SEC_TO_TIME(dOffset));
WHILE match_found DO
SET closed_day = FALSE;
IF contor = 0 THEN
SELECT IFNULL(a.day_of_year, -1), IF(open_time = MAKETIME(0,0,0) AND close_time = MAKETIME(0,0,0), TRUE, FALSE) INTO dYear, closed_day
FROM shop_hours_special a
WHERE a.`type` = dType AND a.day_of_year = dayYear
AND (CURTIME BETWEEN a.open_time AND a.close_time OR (open_time = MAKETIME(0,0,0) AND close_time = MAKETIME(0,0,0)));
SELECT IFNULL(b.day_of_week, -1) INTO dWeek
FROM shop_hours b
WHERE b.`type` = dType AND b.day_of_week = dayWeek AND (b.open_time != MAKETIME(0,0,0) OR b.close_time != MAKETIME(0,0,0)) AND CURTIME BETWEEN b.open_time AND b.close_time ;
ELSE
SELECT IFNULL(a.day_of_year, -1), IF(open_time = MAKETIME(0,0,0) AND close_time = MAKETIME(0,0,0), TRUE, FALSE) INTO dYear, closed_day
FROM shop_hours_special a
WHERE a.`type` = dType AND a.day_of_year = dayYear;
SELECT IFNULL(b.day_of_week, -1) INTO dWeek
FROM shop_hours b
WHERE b.`type` = dType AND b.day_of_week = dayWeek AND (b.open_time != MAKETIME(0,0,0) OR b.close_time != MAKETIME(0,0,0));
END IF;
IF closed_day THEN
SET dYear = -1;
SET dWeek = -1;
END IF;
IF dYear != -1 THEN
SET final_date = MAKEDATE(YEAR(NOW()), dYear);
SET match_found = FALSE;
ELSEIF dWeek != -1 THEN
SET final_date = NOW() + INTERVAL contor DAY;
SET match_found = FALSE;
ELSE
SET contor = contor + 1;
SET dayYear = DAYOFYEAR(NOW() + INTERVAL contor DAY);
SET dayWeek = WEEKDAY(NOW() + INTERVAL contor DAY) + 1;
END IF;
END WHILE;
SELECT final_date;
END$$
DELIMITER ;
样本数据:
CREATE TABLE `shop_hours` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`shop_id` int(11) unsigned NOT NULL,
`type` tinyint(3) NOT NULL DEFAULT '1',
`day_of_week` int(11) NOT NULL,
`open_time` time NOT NULL,
`close_time` time NOT NULL,
PRIMARY KEY (`id`),
KEY `shop_id` (`shop_id`),
CONSTRAINT `shop_hours_ibfk_1` FOREIGN KEY (`shop_id`) REFERENCES `shops` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `shop_hours` (`id`, `shop_id`, `type`, `day_of_week`, `open_time`, `close_time`)
VALUES
(1,1,1,1,'09:30:00','20:00:00'),
(2,1,1,2,'09:30:00','20:00:00'),
(3,1,1,3,'09:30:00','20:00:00'),
(4,1,1,4,'09:30:00','20:00:00'),
(5,1,1,5,'09:30:00','20:00:00'),
(6,1,1,6,'09:30:00','20:00:00'),
(7,1,1,7,'11:00:00','20:00:00'),
(8,1,2,1,'11:30:00','12:30:00'),
(9,1,2,2,'11:30:00','12:30:00'),
(10,1,2,3,'11:30:00','12:30:00'),
(11,1,2,4,'11:30:00','12:30:00'),
(12,1,2,5,'11:30:00','12:30:00'),
(13,1,2,6,'00:00:00','00:00:00'),
(14,1,2,7,'00:01:00','23:00:00');
CREATE TABLE `shop_hours_special` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`shop_id` int(11) unsigned NOT NULL,
`type` tinyint(3) NOT NULL DEFAULT '1',
`day_of_year` int(11) NOT NULL,
`open_time` time NOT NULL,
`close_time` time NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`shop_id`,`type`,`day_of_year`),
KEY `shop_id` (`shop_id`),
CONSTRAINT `shop_hours_special_ibfk_1` FOREIGN KEY (`shop_id`) REFERENCES `shops` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `shop_hours_special` (`id`, `shop_id`, `type`, `day_of_year`, `open_time`, `close_time`)
VALUES
(1,1,1,1,'00:00:00','00:00:00'),
(2,1,1,92,'00:00:00','00:00:00'),
(3,1,1,96,'00:00:00','00:00:00'),
(4,1,1,97,'00:00:00','00:00:00'),
(5,1,1,99,'00:00:00','00:00:00'),
(6,1,1,100,'00:00:00','00:00:00'),
(7,1,1,125,'00:00:00','00:00:00'),
(8,1,1,138,'00:00:00','00:00:00'),
(9,1,1,148,'00:00:00','00:00:00'),
(10,1,1,149,'00:00:00','00:00:00'),
(11,1,2,1,'00:00:00','00:00:00'),
(12,1,2,92,'00:00:00','00:00:00'),
(13,1,2,96,'00:00:00','00:00:00'),
(14,1,2,97,'00:00:00','00:00:00'),
(15,1,2,99,'00:00:00','00:00:00'),
(16,1,2,100,'00:00:00','00:00:00'),
(17,1,2,125,'00:00:00','00:00:00'),
(18,1,2,138,'00:00:00','00:00:00'),
(19,1,2,148,'00:00:00','00:00:00'),
(20,1,2,149,'00:00:00','00:00:00');