How can I parse a timestamp in the format yyyy/doy/hh/mm/ss

4 views (last 30 days)
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
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.

Sign in to comment.

Accepted Answer

Star Strider
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
Michael Balling
Michael Balling on 2 Dec 2016
Very helpful. I modified the script to read '2016:323:15:11:03:114' and it returned 2016 11 19 instead of 2016 11 18. I really need the vector form for my data sets.
Star Strider
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.

Sign in to comment.

More Answers (2)

Jan
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;

Peter Perkins
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

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!