save tic toc in duration style

Hi all, I would like to save my computational time using tic toc but in format duration (i am trying to use duration but I don't know how to save it).
Here is my code, so far I just get the time in second, and exact time give me number separate by comas. What I want to get is something like
1 hour 20 second saving in txt file. Do you guys can help me?
close all, clc, clear all
tStart = tic;
a=load('PE_201507_LPF7Hz_m5L3.dat');
plot(a)
tEnd = toc(tStart)
tEnd = toc(tStart);
time_exec=datevec(tEnd./(60*60*24)) %change time in tictoc to
name=sprintf('exec_time.txt')
dlmwrite (name,time_exec);

1 Comment

Do you have a specific format in mind for the txt file? For now, I will write an answer that should be close to what you want.

Sign in to comment.

Answers (2)

tEnd = 60*60+20
tEnd = 3620
txt = mytime(tEnd)
txt = '1 hour 20 seconds'
writelines(txt,'myfile.txt')
Checking:
type myfile.txt
1 hour 20 seconds
function str = mytime(toa)
spl = nan(1,4);
dpf = 100;
toa = ceil(toa*dpf)/dpf;
spl(4) = rem(toa,60); % seconds
toa = fix(toa/60);
spl(3) = rem(toa,60); % minutes
toa = fix(toa/60);
spl(2) = rem(toa,24); % hours
toa = fix(toa/24);
spl(1) = toa ; % days
idt = spl~=0 | [false(1,3),~any(spl)];
idp = spl~=1 & idt;
fmt = {' %d day',' %d hour',' %d minute',' %g second';'s','s','s','s'};
str = strtrim(sprintf([fmt{[idt;idp]}],spl(idt)));
end
The code below removes the cargo cult programming, removes the sprintf where you aren't actually using it to format a string, and replaces dlmwrite by code intended to write a text file.
I separated out the code to convert a number of seconds to a char vector. It is far from optimal, but since it uses the duration class, it is fairly easy to change to suit your needs. Note that this skips a time element if it is 0 (so it will reproduce your example of 1 hour and 20 seconds).
tStart = tic;
a=load('PE_201507_LPF7Hz_m5L3.dat');
plot(a)
tEnd = toc(tStart);
fid = fopen('exec_time.txt','w');
fprintf(fid,'%s',SecondToTimeStr(tEnd));
fclose(fid);
function str=SecondToTimeStr(sec)
% This function takes a scalar containing the time in seconds.
% The returned value is a char vector.
D = duration(0,0,sec);
str = '';
if hours(D)>0
plural = ''; if hours(D)>1,plural = 's';end
str = [str sprintf('%.0f hour%s',hours(D),plural)];
D = D - hours(floor(hours(D)));
end
if minutes(D)>0
if ~isempty(str),str = [str ', '];end
plural = ''; if minutes(D)>1,plural = 's';end
str = [str sprintf('%.0f minute%s',minutes(D),plural)];
D = D - minutes(floor(minutes(D)));
end
if seconds(D)>0
if ~isempty(str),str = [str ', '];end
plural = ''; if seconds(D)>1,plural = 's';end
str = [str sprintf('%.0f second%s',seconds(D),plural)];
end
end

8 Comments

An even easier way to split the duration into its components is to use the hms function:
n = 12345.67; % sample data
d = seconds(n) % convert between double and duration
d = duration
12346 sec
[numHours, numMinutes, numSeconds] = hms(d)
numHours = 3
numMinutes = 25
numSeconds = 45.6700
check = hours(numHours)+minutes(numMinutes)+seconds(numSeconds)
check = duration
3.4294 hr
check.Format = 's'
check = duration
12346 sec
@Steven Lord: even better would be if DURATION had day, hour, minute, and second properties.
HMS misses the days :(
I had also expected year/month/day/hour/minute/second methods for a duration class. That is at least how I would write it. (I do get there will be ambiguity for the years and month (leap days, average month length, etc))
@Stephen23: Would you expect those properties to be the value of the duration converted into that unit or that component of the duration? So if I had:
du = seconds(61)
du = duration
61 sec
should its minute property be 1 since du is 1 minute plus 1 second, or should it be 61/60 since (61 seconds) * (1/60 minutes/second) gives the result units of minutes?
This seems like a reasonable enhancement request, as long as you state which of those options would be your preference and why. [I expect to see at least a few such enhancement requests, and I'm not sure what the distribution of options is going to be. I'm pretty sure it won't be unanimous, but I'm not certain it'll be 50/50.]
@Rik There are seconds, minutes, hours, and days functions that convert the value of the duration into those units. Having properties or methods that return the components would be possible, but the most natural names are already taken.
du = duration(25, 37, 18)
du = duration
25:37:18
days(du)
ans = 1.0676
hours(du)
ans = 25.6217
minutes(du)
ans = 1.5373e+03
seconds(du)
ans = 92238
If you're doing calendar arithmetic (as opposed to date and time arithmetic) that takes into account things like leap years, you may want to use calendarDuration instead of duration.
notMidnight = datetime('today') + years(1) % add 1 year (duration) = 365.2425 days
notMidnight = datetime
19-Jun-2025 05:49:12
midnight = datetime('today') + calyears(1) % effectively, increment year # by 1
midnight = datetime
19-Jun-2025
Thank you for your customary thoroughness.
I personally would expect this Q to be a common use case: forming some kind of time elapsed string.
So perhaps I would expect this behaviour:
>> du.days
1
>> du.minutes
37
I don't know if I want this to do something that should be done with datetime, but that seems an odd choice, since we're not dealing with dates here.
So perhaps this?
>> char(du.Format('%dd day(s), %HH hour(s), %mm minute(s), %ss.SSS seconds'))
'1 day(s), 1 hour(s), 37 minute(s), 18.000 seconds'
I haven't given this a lot of thought, so perhaps I'm missing an implication that makes this a stupid idea.
"should its minute property be 1 since du is 1 minute plus 1 second"
Yes. This would be useful functionality that exactly mirrors the similarly-named properties of DATETIME.
"...or should it be 61/60 since (61 seconds) * (1/60 minutes/second) gives the result units of minutes?"
No, that functionality is already easily available using the functions DAYS, HOURS, etc.
@Rik Making the Format property for duration objects more flexible (especially with respect to literal characters) like the Format property for datetime objects seems like a reasonable enhancement request.
dt = datetime('today', Format = "'It is' eeee, MMMM d, yyyy")
dt = datetime
It is Thursday, June 20, 2024
It probably wouldn't have the exact syntax you showed (fprintf-style format specs aren't always the easiest piece of functionality to understand) but if you could specify the duration format as something like
fmt = "d 'days', h 'hours'"
fmt = "d 'days', h 'hours'"
would that satisfy the use cases you have in mind?
@Stephen23 Having du.minutes [property access] and minutes(du) [method call] return different things 1) may not be possible without perhaps careful overloading of both types of indexing and 2) sounds like a strong source of confusion going forward. We have enough trouble at times with functions that are named similarly but not identically! [Example: one of the functions findstr and strfind is listed as discouraged on its documentation page. Without checking, can you tell me which one?]
Having a property named minute and a method named minutes is technically possible, but again is likely to require some thought and/or checking the documentation each time you use them to determine which one you want to use. I can think of many cases where we have function names that differ by one extra character but usually those "just plain work" in common cases where you pass the inputs valid for one into the other (eig and eigs is one example) or the meaning of the extra character is IMO easy to understand and/or remember in context (sin for radian-based sine, sind for degree-based sine.)
Stephen23
Stephen23 on 20 Jun 2024
Edited: Stephen23 on 20 Jun 2024
@Steven Lord: for the properties I would stick to the singular, just like DATETIME does.
Or if confusion with the methods is a concern, then the properties could be simply d, h, m, s.

Sign in to comment.

Categories

Asked:

on 19 Jun 2024

Edited:

on 20 Jun 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!