Azzera filtri
Azzera filtri

Calculate duration from cell with date hours with Matlab 2013a

3 visualizzazioni (ultimi 30 giorni)
I have a cell array of more than 16700 rows and 3 column as in the example below:
'01/01/2014' '12:00:00' 'AM'
'01/01/2014' '06:00:00' 'AM'
'01/01/2014' '10:00:00' 'AM'
'01/01/2014' '12:00:00' 'PM'
'09/04/2014' '11:00:00' 'PM'
I would like to calculate the duration of two chosen dates and time (for example the last row-first raw=number of days, hours and seconds). My big problem is that I have a R2013a version of Matlab. So I can't use DateTime, I tried this:
newA = cellfun(@(s) strsplit(s, ' '), DateTime, 'UniformOutput', false);
DateTimeSep = vertcat(newA{:});
%%Calculs de durée et récupération de données
date=datenum(DateTimeSep(:,1),'mm/dd/yyyy');
d=datestr(date(1256,1)-date(1,1), 'dd')
Time=DateTimeSep(10,2)-DateTimeSep(1,2)% I didn't try to consider the AM PM problem yet....
I get d=04 (which is false) and for time I get: "Undefined function 'minus' for input arguments of type 'cell'"

Risposta accettata

Jan
Jan il 3 Apr 2017
Modificato: Jan il 8 Apr 2017
% [Don't use this - see [EDITED 2] for a nicer solution!]
D = {'01/01/2014' '12:00:00' 'AM'; ...
'01/01/2014' '06:00:00' 'AM'; ...
'01/01/2014' '10:00:00' 'AM'; ...
'01/01/2014' '12:00:00' 'PM'; ...
'09/04/2014' '11:00:00' 'PM'};
DateV = datevec(strcat(D(:, 1), '#', D(:, 2)), 'mm/dd/yyyy#HH:MM:SS');
IsPM = strcmpi(D(:, 3), 'PM');
pstPM = (DateV(:, 4) < 12 & IsPM);
DateV(pstPM, 4) = DateV(pstPM, 4) + 12; % 12:01PM ==> 12:01, 1:01PM ==> 13:01
midAM = (DateV(:, 4) == 12 & ~IsPM);
DateV(midAM, 4) = 0; % 12:01AM ==> 00:01
DateN = datenum(DateV);
Now the time difference can be calculated by a simple subtraction.
datevec(DateN(end) - DateN(1)) % [EDITED, DateTimeN -> DateN]
[EDITED 2] No, the conversion of the time difference to months and years is not meaningful: It is not clear if the "month" has 28, 29, 30 or 31 days, if it concerns the difference between dates. Better:
Duration = DateN(end) - DateN(1);
DurationDays = fix(Duration);
Tmp = rem(Duration, 1); % Time
DurationHour = floor(Tmp * 24);
DurationMin = floor(rem(Tmp * 1440, 60));
DurationSec = round(rem(Tmp * 86400, 60));
Sorry, this is too ugly! Nicer:
D = {'02/14/2014', '10:02:04', 'AM'; ...
'02/26/2014', '01:00:00', 'PM'};
DateN = datenum(strcat(D(:, 1), '#', D(:, 2), '#', D(:, 3)), ...
'mm/dd/yyyy#HH:MM:SS#AM');
Duration = DateN(end) - DateN(1);
DDays = fix(Duration);
[~,~,~, Dhour, Dmin, Dsec] = datevec(rem(Duration, 1));
  7 Commenti
dpb
dpb il 25 Apr 2017
Well, that way splits on a a blank instead of parsing the date/time fields. Apparently there's one (or more) record that aren't all the same length. After the split, look at
l=cellfun(@length, newA, 'UniformOutput', false);
and use min() max() or unique() to see who's the odd man out.
That will tell you what is the problem in concatenating. But, the real answer is to use the correct format string and convert directly.

Accedi per commentare.

Più risposte (1)

dpb
dpb il 3 Apr 2017
Modificato: dpb il 3 Apr 2017
If using version prior to introduction of datetime, just use date numbers directly...
>> dn=datenum([char(A{:,1}) char(A{:,2}) char(A{:,3})],'mm/dd/yyyyHH:MM:SSAM'); % to datenumbers
>> dt=dn(end)-dn(1); % a difference first-last
>> [y,m,d,h,m,s]=datevec(dt) % numeric difference in y,m,d,...
y =
0
m =
9
d =
2
h =
23
m =
0
s =
0
>> datestr(dt,'dd HH:MM:SS') % as string in days HH:MM:SS
ans =
02 23:00:00
>>
ADDENDUM
Hmmm...I thought datestr and datevec were just a little smarter than are--I was thinking they would take the value 246 days and reflect that in the datestr conversion if used a field of days only. But, they wrap internally to months so if want days and hours of elapsed time use
days=fix(dt);
then can convert from
fracdays=dt=days;
with datevec datestr to get the time fields in whichever form desired.

Categorie

Scopri di più su Dates and Time 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!

Translated by