I have a table in mysql like this:
+------------+------------+------------+------------+
| date | user_id | start_hour | end_hour |
+-----------
This will give you the end time blocks
SELECT T_a.end_hour
FROM (table AS T_a) LEFT JOIN (table AS T_b)
ON (T_a.`date`=T_b.`date` AND T_b.start_hour<=T_a.end_hour AND T_b.end_hour>T_a.end_hour)
WHERE T_b.user_id IS NULL
This will give you the start time block
SELECT T_a.start_hour
FROM (table AS T_a) LEFT JOIN (table AS T_b)
ON (T_a.`date`=T_b.`date` AND T_b.start_hour=T_a.start_hour)
WHERE T_b.user_id IS NULL
These queries will look for starts or ends that are uncrossed or butted up to other slots. so 10-11 11-12 will give 10 start, 12 end = free time is 08-10 and 12-21
So free time is 08:00 (unless its a start time) upto first 'start' time, then matching pairs of END->START upto last END->21:00 (unless 21:00 IS the last end)
N.B. You'll need to add the date in too.