If for a report, you should simply be able to make a query / join that give two records within these conditions from the source, starting ... Without SQL-Server 2008, I can only offer pseudo-code query for you.
The first part gets all the records based on any state of your range that you want to show. The value "OutTime" is arbitrary ... if it is on the same day, then there is no cross, just use the exit time. If this happens the next day, use casting to dynamically create the date βYYYY-MM-DDβ (which will be 00:00:00 by default), as you want as the OUT time.
UNION will ONLY capture the same records that were registered with FIRST, where I / O dates differ. Thus, we KNOW that we want OutTime to act as InTime, but based on the time β00:00:00β, therefore the exact same castration of the date and time field is performed, and for these records just use the final value βOutTimeβ as it is.
An additional column for βTimeSplitβ from β1β or β2β is to make sure that we can still group the employee ID, but from this make sure that the first records (initial shift) of any of them have the record β2 "to cover the day in their shift.
select tc.EmployeeID, '1' as TimeSplit, tc.InTime, case when datepart( dd, tc.InTime ) = datepart( dd, tc.OutTime ) then tc.OutTime else CAST( CAST( datepart(yyyy, tc.OutTime ) AS varchar) +'-'+ CAST( datepart( mm, tc.OutTime ) AS varchar) +'-'+ CAST( datepart( dd, tc.OutTime ) AS varchar) AS DATETIME) end as OutTime from TimeCard tc where YourDateRangeConditions... ORDER BY tc.EmployeeID, TimeSplit UNION ALL select tc.EmployeeID, '2' as TimeSplit, CAST( CAST( datepart(yyyy, tc.OutTime ) AS varchar) +'-'+ CAST( datepart( mm, tc.OutTime ) AS varchar) +'-'+ CAST( datepart( dd, tc.OutTime ) AS varchar) AS DATETIME) end as InTime tc.OutTime from TimeCard tc where YourDateRangeConditions... AND NOT datepart( dd, tc.InTime ) = datepart( dd, tc.OutTime )