Turn number to datetime
31 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Dylan den Hartog
il 16 Mag 2021
Modificato: Cris LaPierre
il 17 Mag 2021
Is there an easy way to convert a number, e.g. 101416517, to a time: 10:14:16.517?
Thanks in advance!
0 Commenti
Risposta accettata
Cris LaPierre
il 17 Mag 2021
Modificato: Cris LaPierre
il 17 Mag 2021
Not the prettiest, but once we look at the actual data, the approach shared earlier need to be customized.
Your PacketCounter column appears to be the information you want to convert to time of day. Row 8 contains the date information. Since I assume the goal is to automate this, I suggest using textscan to capture the date, then readtable to read in the table of values.
% Capture the start date
fid = fopen('Enkel_links_20210403_235559_998.csv');
% Textscan does not support time zones, so read in as a string and convert.
hdr = textscan(fid,'%*s %q %*[^eof]','HeaderLines',7,'Delimiter',';');
startD = datetime(hdr{1}{1},'InputFormat','yyyy-MM-dd HH:mm:ss.SSS Z','TimeZone','Europe/London',"Format","dd-MMM-uuuu HH:mm:ss.SSS");
startD.TimeZone = ''
fclose(fid);
I dropped the time zone. You can keep it if you want.
With the date, you can now work out the process for converting PacketCounter to times. You can use pieces of what has been shown already.
T = readtable('Enkel_links_20210403_235559_998.csv','NumHeaderLines',10)
% Get start date without time
D0 = dateshift(startD,"start","day")
% Convert PacketNumber to strings, padding with zeros so always 9 characters
% Then convert strings to durations by just keeping time of day
spf = @(x) sprintf('%09d',x);
% Add result to a new column to the end of the table
T.Datetime = timeofday(datetime(rowfun(spf,T(:,'PacketCounter'),"OutputFormat","cell"),'InputFormat',"HHmmssSSS"))
% Add start date to duration
T.Datetime = T.Datetime + D0
% Determine new day as when there is a negative change in time
df = [0; diff(T.Datetime)<0]
% Use cumsum on logical array to indicate how many days to add to date
T.Datetime = T.Datetime + cumsum(days(df))
% Convert to timetable
TT = table2timetable(T,'RowTimes','Datetime')
As an aside, would it make more sense to use SampleTimeFine? You'd have to figure out what zero time is, but it appears 1 ms is equal to a change of 16,667, or 1E6/60. That may have something to do with the indicated OutputRate: 60Hz;
0 Commenti
Più risposte (4)
Cris LaPierre
il 16 Mag 2021
Modificato: Cris LaPierre
il 16 Mag 2021
d=101416517;
D=datetime(num2str(d),'InputFormat','HHmmssSSS',"Format","HH:mm:ss.SSS")
2 Commenti
Cris LaPierre
il 16 Mag 2021
dpb makes a good point that a duration may be more appropriate if you truly just want the time. Here is an approach to get that:
d=101416517;
D=datetime(num2str(d),'InputFormat','HHmmssSSS')
D = D-dateshift(D,"start","day");
D.Format="hh:mm:ss.SSS"
dpb
il 16 Mag 2021
>> dtn=datetime(string(tn),'InputFormat','HHmmssSSS','Format','HHmmss.SSS')
dtn =
datetime
101416.517
>>
NB: However, a MATLAB datetime must include a date; in the above without an input date field, the current date at the local time of the conversion will be used -- for example, carrying on from above
>> dtn.Format='default'
dtn =
datetime
16-May-2021 10:14:16
>>
To hold only the time, one would have to use a duration variable, but, unfortunately, duration() is a weak sibling --
>> duration(string(tn),'InputFormat','HHmmssSSS','Format','hh:mm:ss.SSS')
Error using duration (line 299)
Unsupported format 'HHmmssSSS'. See the documentation of 'InputFormat' for valid formats.
>>
The general input format strings aren't recognized; nor can you be fully general in the output format requested. Real slip-up in quality of implementation arena.
So, you can coerce in round about way by subtracting the y,m,d from the datetime value...
>> dun=duration(dtn-datetime(year(dtn),month(dtn),day(dtn)),'Format','hh:mm:ss.SSS')
dun =
duration
10:14:16.517
>>
Alternatively, you can format the string in a recognizable pattern...with some effort
>> stn=num2str(tn);
>> sprintf('%2s:%2s:%2s.%3s',stn(1:2),stn(3:4),stn(5:6),stn(7:9))
ans =
'10:14:16.517'
>>
Or, you can do all the arithmetic to modulo the pieces by the proper powers of 10 to numerically separate out the pieces...
0 Commenti
Dylan den Hartog
il 16 Mag 2021
3 Commenti
Cris LaPierre
il 16 Mag 2021
Yes, if your times reset to 0 each day, this will be a problem. What data do you have to work with? Could you share a data set? You can attach it using the paperclip icon.
Dylan den Hartog
il 16 Mag 2021
1 Commento
Steven Lord
il 16 Mag 2021
Let's take a series of datetime values.
N = datetime('now')
dur = hours(randi([0 5], 10, 1)) + ... % Between 0 and 5 hours from now
minutes(randi([0 59], 10, 1)) + ... % and 0 to 59 minutes
seconds(randi([0 59], 10, 1)); % and 0 to 59 seconds
dur.Format = 'hh:mm:ss';
dur = sort(dur)
DT = N+dur
Given N and the datetime array DT we can recreate dur.
offset = DT - N
And if we want to figure out what would happen if we had started this count from say 4 AM today instead of from N:
newbase = datetime(2021, 5, 16, 4, 0, 0)
newDT = newbase + offset
The times in newDT should be about 14.5 hours before the times in DT.
difference = DT - newDT
differenceInHours = hours(difference)
In general:
- datetime + datetime gives an error (rather than a play between the pitcher and catcher.)
- datetime - datetime gives a duration
- datetime + duration gives a datetime
- datetime - duration gives a datetime
- duration + datetime gives a datetime
- duration - datetime gives an error
- duration + duration gives a duration
- duration - duration gives a duration
Vedere anche
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!