Calculate time intervals in an hour
    4 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
    Matheus  Pacifici
 il 27 Set 2019
  
    
    
    
    
    Commentato: Adam Danz
    
      
 il 27 Set 2019
            I have a table with 2 columns: start time and end time. For each row the interval interval (end time -start time) represents the duration. I need to find the toal duration per each hour. Note that the time intervals not necessarily are restricted to a specific hour. A part of the table looks like:
        Start Time                                            End time
    13-Sep-2019 04:12:37            13-Sep-2019 04:16:34
    13-Sep-2019 04:18:36            13-Sep-2019 04:33:36
    13-Sep-2019 04:33:36            13-Sep-2019 04:48:36
    13-Sep-2019 04:48:36            13-Sep-2019 05:03:36
    13-Sep-2019 05:03:36            13-Sep-2019 05:18:36
    13-Sep-2019 05:18:37            13-Sep-2019 05:33:37
    13-Sep-2019 05:33:37            13-Sep-2019 05:48:37
    13-Sep-2019 05:48:37            13-Sep-2019 06:03:37
    13-Sep-2019 06:03:37            13-Sep-2019 06:18:38
    13-Sep-2019 06:18:38            13-Sep-2019 06:33:38
The ideal output would be a table with two columns: hour and total time intervals.
Ex:
            Hour                                    Total Duration
 13-Sep-2109 04:00:00                           X
13-Sep-2109 05:00:00                            Y
13-Sep-2109 06:00:00                            Z
5 Commenti
  the cyclist
      
      
 il 27 Set 2019
				I meant for you to upload the data in a MAT file (using the paper clip icon). It's not very easy to paste those data to create variables in the workspace for testing.
Risposta accettata
  the cyclist
      
      
 il 27 Set 2019
        
      Modificato: the cyclist
      
      
 il 27 Set 2019
  
      % Create an input data table
startDateStr = {'2014-05-26 04:44:44';
                '2014-05-26 04:45:44';
                '2014-05-26 05:44:44';
                '2014-05-26 05:45:44';
                };
endDateStr   = {'2014-05-26 04:44:55';
                '2014-05-26 04:45:56';
                '2014-05-26 05:44:57';
                '2014-05-26 05:45:58';
                };
startTime = datetime(startDateStr,'InputFormat','yyyy-MM-dd hh:mm:ss');
endTime = datetime(endDateStr,'InputFormat','yyyy-MM-dd hh:mm:ss');
tbl = table(startTime,endTime);
% Find the unique hours, and the index to those hours
hourOfDay = dateshift(tbl.startTime,'start','hour');
[Hour,~,whichHour] = unique(hourOfDay);
% Find the durations (in seconds, but could be something else)
durationsInSeconds = seconds(tbl.endTime - tbl.startTime);
% Find the total duration for each of the unique hours
TotalDuration = accumarray(whichHour,durationsInSeconds);
% Put the result in a table
output = table(Hour,TotalDuration)
6 Commenti
  Adam Danz
    
      
 il 27 Set 2019
				If a starttime and endtime have two different hours (03:59 to 04:59), the entire duration will be assigned to the first hour (3:00) since "whichHour" is based on the starting hour.  So your hunch is correct that this would cause those simptoms (along with the span >24hr).  
Più risposte (1)
  Adam Danz
    
      
 il 27 Set 2019
        
      Modificato: Adam Danz
    
      
 il 27 Set 2019
  
      I've made lots of comments to explain what's going on.  But here's a summary. 
This approach interpolates each start:end time to second-resolution, combines all of those vectors into one, and applies unique() to get rid of any duplicates.  That results in a single long vector of timestamps at 1-second-resolution that cover every start:end without overlap.  Then we use histcounts() to count the number of seconds per hourly bin.  The hourly bins span across days (or months or years) and covers the entire range of your data.  The number of seconds per hour are converted to number of minutes per hour.
The result is a table displayed below. 
The "Minutes" column can also be displayed in "durations".  You'll see a commented line in the code that makes that conversion, if desired.  
% Read in data 
T = readtable('RepoInSeatHistory.xlsx'); 
T.startTime = datetime(T.startTime,'InputFormat','yyyy-MM-dd HH:mm:ss +0000'); 
T.endTime = datetime(T.endTime,'InputFormat','yyyy-MM-dd HH:mm:ss +0000'); 
% Determine the min and max datetime to the hour (rounding up/down)
minHr = min(dateshift(T.startTime,'start','hour'));
maxHr = max(dateshift(T.startTime,'end','hour'));
% Create bins that span every day/hour  (this allows for spans >24 hrs)
hrBins = minHr : hours(1) : maxHr; 
% Interpolate all start:end to second-resolution
dtInterpCell = arrayfun(@(i)T.startTime(i) : seconds(1) : T.endTime(i), 1:size(T,1),'UniformOutput',false);
dtInterp = dateshift([dtInterpCell{:}],'end','second');  %a long vector of all start:end in second-resolution
% Remove any duplicates (this avoids problem of overlapping start-end values)
dtInterp = unique(dtInterp); %note, the order of the datetimes doesn't matter
% Now simply use histcounts to determine the number of seconds within hourly bins 
% that potentially span multiple days
secondsPerHour = histcounts(dtInterp,hrBins); 
% Convert to minutes/hr
% This may result in decimals that represent partial minutes since we're measuring
% at second-resolution.  If that's not desired, you can use floor() or ceil() to
% round down or up. 
MinutsPerHour = secondsPerHour/60;
% MinutsPerHour = minutes(secondsPerHour/60); % Alternative: minute durations
% Put results in a table
hrBins(end) = []; %remove last edge
Tout = table(hrBins(:), MinutsPerHour(:),'VariableNames',{'HourBins', 'Minutes'});
Result
Tout =
  19×2 table
          HourBins          Minutes
    ____________________    _______
    12-Sep-2019 21:00:00    29.333 
    12-Sep-2019 22:00:00        60 
    12-Sep-2019 23:00:00        60 
    13-Sep-2019 00:00:00        58 
    13-Sep-2019 01:00:00        56 
    13-Sep-2019 02:00:00    57.983 
    13-Sep-2019 03:00:00        60 
    13-Sep-2019 04:00:00    57.983 
    13-Sep-2019 05:00:00        60 
    13-Sep-2019 06:00:00        60 
    13-Sep-2019 07:00:00        60 
    13-Sep-2019 08:00:00        60 
    13-Sep-2019 09:00:00        60 
    13-Sep-2019 10:00:00        60 
    13-Sep-2019 11:00:00        60 
    13-Sep-2019 12:00:00        60 
    13-Sep-2019 13:00:00    32.517 
    13-Sep-2019 14:00:00      48.2 
    13-Sep-2019 15:00:00    9.4833 
2 Commenti
  Adam Danz
    
      
 il 27 Set 2019
				I wonder what release of Matlab you are using.  Histcounts does take datetime inputs (at least in r2019a and b).  Search for "datetime" on the histcounts documentation page:
Glad I could help!
Vedere anche
Categorie
				Scopri di più su Data Type Conversion in Help Center e File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!