Well that was an interesting and fun problem to work on.  +1
So lets start up with a setup:
CREATE TABLE d (start_dt datetime, end_dt datetime)
INSERT INTO d VALUES ('3/5/2010 11:27', '3/5/2010 13:04')
INSERT INTO d VALUES ('3/5/2010 11:29', '3/5/2010 11:55')
INSERT INTO d VALUES ('3/5/2010 13:13', '3/5/2010 13:37')
INSERT INTO d VALUES ('3/5/2010 13:13', '3/5/2010 13:37')
INSERT INTO d VALUES ('3/5/2010 14:55', '3/5/2010 15:22')
INSERT INTO d VALUES ('3/5/2010 14:55', '3/5/2010 15:22')
INSERT INTO d VALUES ('3/5/2010 15:15', '3/5/2010 17:45')
Here is the code to actually calculate it, all via TSQL:
-- Create a cursor that we will use to loop over all the items in the base table
DECLARE cur CURSOR FOR SELECT start_dt, end_dt FROM d
-- Temp variables to store each rows data
DECLARE @start_dt datetime, @end_dt datetime
-- Temp table to hold the "adjusted" rows
DECLARE @d TABLE (id int identity, start_dt datetime, end_dt datetime)
OPEN cur
FETCH NEXT FROM cur INTO @start_dt, @end_dt
WHILE @@FETCH_STATUS = 0
BEGIN
    -- Start by deleting any rows contained entirely within the current rows timeframe
    DELETE FROM @d WHERE start_dt BETWEEN @start_dt AND @end_dt AND end_dt BETWEEN @start_dt     AND @end_dt
    DECLARE @id_start_in int = -1, @id_end_in int = -1
    SELECT @id_start_in = id FROM @d WHERE @start_dt BETWEEN start_dt AND end_dt
    SELECT @id_end_in = id FROM @d WHERE @end_dt BETWEEN start_dt AND end_dt
    -- If our start and end dates are not contained in any other set, add it as a new row
    IF (@id_start_in = -1 AND @id_end_in = -1)
        INSERT INTO @d (start_dt, end_dt) VALUES (@start_dt, @end_dt)
    -- If our start date and end dates are both contained in the same row, ignore because we are overlapping that row
    -- If our start date and end dates are in two different rows, we combine those two
    -- For example if there are 3 rows, 1-3, 2-5, 4-6, we actually have full coverage from 1-6
    IF (@id_start_in != @id_end_in AND @id_start_in != -1 AND @id_end_in != -1)
    BEGIN
        -- Expand the start row to end at the same time the row our end time is in
        UPDATE @d SET end_dt = (SELECT end_dt FROM @d WHERE id = @id_end_in) WHERE id = @id_start_in
        -- Delete the row our end time is in
        DELETE FROM @d WHERE id = @id_end_in
    END
    -- If our start date is contained in a row but our end date isnt, extend the existing row
    -- to end at our end date
    IF (@id_start_in != -1 AND @id_end_in = -1)
        UPDATE @d SET end_dt = @end_dt WHERE id = @id_start_in
    -- If our end date is contained in a row but our start date isnt, extend the existing row
    -- to start at our start time
    IF (@id_start_in = -1 AND @id_end_in != -1)
        UPDATE @d SET start_dt = @start_dt WHERE id = @id_end_in
    FETCH NEXT FROM cur INTO @start_dt, @end_dt
END
CLOSE cur
DEALLOCATE cur
-- Show the end table
SELECT start_dt, end_dt, DATEDIFF(MINUTE, start_dt, end_dt) FROM @d
-- Sum up to get the minutes and calculate the hours
SELECT SUM(DATEDIFF(MINUTE, start_dt, end_dt)) AS MINUTES, CAST(SUM(DATEDIFF(MINUTE, start_dt, end_dt)) AS DECIMAL) / 60 AS HOURS FROM @d