Skip to content

Instantly share code, notes, and snippets.

@SysProfile
Created May 24, 2023 15:56
Show Gist options
  • Save SysProfile/5ed29f28a931f487946857cf0c90834b to your computer and use it in GitHub Desktop.
Save SysProfile/5ed29f28a931f487946857cf0c90834b to your computer and use it in GitHub Desktop.
Returns the number of seconds between two dates with times. You can indicate if you want to include only working days. If you add the table, holidays are excluded
CREATE TABLE `holliday_table` (
`_date` date NOT NULL DEFAULT '0000-00-00',
`_desc` varchar(60) NOT NULL DEFAULT '' COMMENT 'Description',
PRIMARY KEY (`_date`),
KEY `_desc` (`_desc`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Holliday table';
DROP FUNCTION IF EXISTS SECONDS_BETWEEN_TIMESTAMP;
DELIMITER $$
CREATE FUNCTION `SECONDS_BETWEEN_TIMESTAMP`(START_TIMESTAMP TIMESTAMP, END_TIMESTAMP TIMESTAMP, RETURN_RESULT VARCHAR (20)) RETURNS BIGINT(20) CHARSET utf8
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE TOTAL_SECS INTEGER;
DECLARE START_DATE DATE;
DECLARE END_DATE DATE;
DECLARE TOTAL_DAY_SAT INTEGER;
DECLARE TOTAL_DAY_SUN INTEGER;
DECLARE TOTAL_DAY_WEND INTEGER;
DECLARE TOTAL_HOLLIDAY INTEGER;
DECLARE RESULT INTEGER;
DECLARE CURR_DATE DATE;
IF (TIMESTAMPDIFF(SECOND, START_TIMESTAMP, END_TIMESTAMP) < 0) THEN RETURN -1; END IF;
SET TOTAL_SECS = TIMESTAMPDIFF(SECOND, START_TIMESTAMP, END_TIMESTAMP);
IF (RETURN_RESULT = "SECS_TOTAL") THEN RETURN TOTAL_SECS; END IF;
SET START_DATE = CAST(START_TIMESTAMP AS DATE);
SET END_DATE = CAST(END_TIMESTAMP AS DATE);
IF (DATEDIFF(END_DATE, START_DATE) > 7) THEN
SET TOTAL_DAY_SAT = (FLOOR(DATEDIFF(END_DATE, START_DATE) / 6) * 86400);
SET TOTAL_DAY_SUN = (FLOOR(DATEDIFF(END_DATE, START_DATE) / 7) * 86400);
ELSE
SET CURR_DATE = START_DATE;
SET TOTAL_DAY_SAT = 0;
SET TOTAL_DAY_SUN = 0;
loop_label: LOOP
IF (DAYNAME(CURR_DATE) = "Saturday") THEN
SET TOTAL_DAY_SAT = TOTAL_DAY_SAT + 1;
END IF;
IF (DAYNAME(CURR_DATE) = "Sunday") THEN
SET TOTAL_DAY_SUN = TOTAL_DAY_SUN + 1;
END IF;
SET CURR_DATE = DATE_ADD(CURR_DATE, INTERVAL 1 DAY);
IF CURR_DATE > END_DATE THEN
SET TOTAL_DAY_SAT = TOTAL_DAY_SAT * 86400;
SET TOTAL_DAY_SUN = TOTAL_DAY_SUN * 86400;
LEAVE loop_label;
END IF;
ITERATE loop_label;
END LOOP;
END IF;
SET TOTAL_DAY_WEND = TOTAL_DAY_SAT + TOTAL_DAY_SUN;
IF (RETURN_RESULT = "SECS_WO_WENDS") THEN RETURN (TOTAL_SECS - TOTAL_DAY_WEND); END IF;
IF (RETURN_RESULT = "SECS_WO_SAT") THEN RETURN (TOTAL_SECS - TOTAL_DAY_SAT); END IF;
IF (RETURN_RESULT = "SECS_WO_SUN") THEN RETURN (TOTAL_SECS - TOTAL_DAY_SUN); END IF;
SET TOTAL_HOLLIDAY = IFNULL((SELECT SUM(IF(holliday_table._date BETWEEN START_DATE AND END_DATE, 1, 0)) AS numofdays FROM holliday_table), 0) * 86400;
IF (RETURN_RESULT = "SECS_WO_HOLLIDAYS") THEN RETURN (TOTAL_SECS - TOTAL_HOLLIDAY); END IF;
IF (RETURN_RESULT = "SECS_ONLY_WORKDAYS") THEN RETURN (TOTAL_SECS - (TOTAL_HOLLIDAY + TOTAL_DAY_WEND)); END IF;
SET RESULT = 0;
RETURN RESULT;
END
$$
DELIMITER ;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment