How can I parse a timestamp in the format yyyy/doy/hh/mm/ss
4 views (last 30 days)
Show older comments
I am running R2014b. How can I parse a UTC timestamp in the format yyyy/doy/hh/mm/ss where doy (day of year) is an integer value 1 to 366. I want to convert doy/hh/mm/ss into seconds.
1 Comment
Stephen23
on 3 Dec 2016
With R2014b you can use datetime objects to achieve this. For earlier versions you can use my FEX submission datenum8601, which converts ISO 8601 dates and timestamps to serial date numbers. It would be easy to apply to your use case, you would just need to change the separator characters to match the ISO 8601 standard. Note that the ISO standard calls the DOY timestamp an "ordinal" date.
Accepted Answer
Star Strider
on 2 Dec 2016
One approach:
str = '2016/183/13/20/15';
fieldc = regexp(str, '/', 'split'); % Parse
fieldn = cellfun(@str2num, fieldc); % Convert To Double
dn = datenum([fieldn(1), 01, 01]) + fieldn(2); % Convert To [Year Month Day]
dv = datevec(dn) + [0 0 0 fieldn(3:end)]; % Add ‘hh’ ‘mm’ ‘ss’ To Vector
secs = etime(dv, [fieldn(1) 01 01 0 0 0]); % Use ‘etime’ To Convert To Seconds From Beginning Of Year
This could possibly be vectorised, but it might be easiest to create it as a function file and parse the dates in a loop. This is a one-off for each set of data (save the converted vector of ‘seconds’), so small inefficiencies could be tolerable. You will probably have to tweak it to work with your data, but that should be straightforward.
2 Comments
Star Strider
on 2 Dec 2016
The correction for that is to experiment with the start date.
Change these lines to:
dn = datenum([fieldn(1) 0 0]) + fieldn(2); % Convert To [Year Month Day]
and:
seconds = etime(dv, [fieldn(1) 0 0 0 0 0]); % Use ‘etime’ To Convert To Seconds From Beginning Of Year
(I don’t know what the ‘114’ is. I’m guessing milliseconds.)
That gave me the correct date. You must have made the vectors compatible in your code, so ignore my vector lengths if they conflict with yours.
You will have to use this in a loop, either as I wrote here or saved to its own function file. The ‘problem’ is that the regexp call (and the related strsplit function that invokes it internally) do not take vector inputs, so you have to pass the strings to them one at a time. That shouldn’t be too time-consuming if you only have to do it once for each data set, and store the output vectors for each in their own arrays.
More Answers (2)
Jan
on 2 Dec 2016
Edited: Jan
on 5 Dec 2016
Str = '2016/183/13/20/15';
dv = sscanf(Str, '%d/%d/%d/%d/%d', [1, 5]);
sec = dv(2:5) * [86400; 3600; 60; 1] - 86400;
The subtraction of 86400 considers, that the doy start at 1 and not at 0.
This works for cell strings also very efficiently:
CStr = {'2016/183/13/20/15', '2016/194/08/20/15'};
Str = sprintf('%s*', CStr{:});
dv = sscanf(Str, '%d/%d/%d/%d/%d*', [5, inf]).';
sec = dv(:, 2:5) * [86400; 3600; 60; 1] - 86400;
0 Comments
Peter Perkins
on 2 Dec 2016
You have R2014b, use datetime:
>> str = '2016/183/13/20/15';
>> d = datetime(str,'InputFormat','yyyy/DDD/HH/mm/ss')
d =
01-Jul-2016 13:20:15
Seconds since ... I think you mean start of year:
>> t = d - dateshift(d,'start','year')
t =
4381:20:15
>> s = seconds(t)
s =
15772815
But "seconds since 1970" is also common:
>> t = posixtime(d)
t =
1467379215
0 Comments
See Also
Categories
Find more on Data Type Conversion in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!