Reputation: 552
I am trying to create a datevec series of dates and times, spaced by 20 minutes, with the minutes column being exactly 0, 20 and 40 with a given starting and ending time. First I create a 20 minute difference value
datenum_20_min_diff = datenum( [ 2021 , 1 , 27 , 17 , 0 ] ) - datenum( [ 2021 , 1 , 27 , 16 , 40 ] ) ;
and then try to create the required datevec series
s = datevec( ( datenum([2021,1,27,22,0]) : datenum_20_min_diff : datenum([2021,1,28,11,0]) )' ) ;
which works for the first few entries but then drifts from what I expect. What I get is (with the minutes column slightly tidied up for ease of viewing)
2.0210e+03 1.0000e+00 2.7000e+01 2.2000e+01 0 0
2.0210e+03 1.0000e+00 2.7000e+01 2.2000e+01 20 0
2.0210e+03 1.0000e+00 2.7000e+01 2.2000e+01 40 0
2.0210e+03 1.0000e+00 2.7000e+01 2.3000e+01 0 0
2.0210e+03 1.0000e+00 2.7000e+01 2.3000e+01 19 6.0000e+01
2.0210e+03 1.0000e+00 2.7000e+01 2.3000e+01 39 6.0000e+01
2.0210e+03 1.0000e+00 2.7000e+01 2.3000e+01 59 6.0000e+01
and what I want/expected is
2.0210e+03 1.0000e+00 2.7000e+01 2.2000e+01 0 0
2.0210e+03 1.0000e+00 2.7000e+01 2.2000e+01 20 0
2.0210e+03 1.0000e+00 2.7000e+01 2.2000e+01 40 0
2.0210e+03 1.0000e+00 2.7000e+01 2.3000e+01 0 0
2.0210e+03 1.0000e+00 2.7000e+01 2.3000e+01 20 0
2.0210e+03 1.0000e+00 2.7000e+01 2.3000e+01 40 0
2.0210e+03 1.0000e+00 2.7000e+01 2.3000e+01 0 0
What am I doing wrong?
Upvotes: 1
Views: 164
Reputation: 552
I have solved my problem by "cleaning up" the output. The "cleaning" code is shown below,
## create a new_date_vec
new_date_vec = datevec( ( datenum(data_ordbk_last) : datenum_20_min_diff : datenum(recent_update_time) )' ) ;
## and clean it up
seconds_60 = find( new_date_vec( : , 6 ) != 0 ) ; new_date_vec( seconds_60 , 6 ) = 0 ;
minutes_19 = find( new_date_vec( : , 5 ) == 19 ) ; new_date_vec( minutes_19 , 5 ) = 20 ;
minutes_39 = find( new_date_vec( : , 5 ) == 39 ) ; new_date_vec( minutes_39 , 5 ) = 40 ;
minutes_59 = find( new_date_vec( : , 5 ) == 59 ) ; new_date_vec( minutes_59 , 5 ) = 0 ;
new_date_vec( minutes_59 , 4 ) = new_date_vec( minutes_59 , 4 ) .+ 1 ;
hours_24 = find( new_date_vec( : , 4 ) == 24 ) ; new_date_vec( hours_24 , 4 ) = 0 ;
new_date_vec( hours_24 , 3 ) = new_date_vec( hours_24 .+ 1 , 3 ) ;
which gives output in the format I want.
Re: Tasos Papastylianou's answer - It was important to get the format just right as later on in my code I am using the ismember function with the optional "rows" argument, so the format of the different rows must match.
Re: Tasos Papastylianou's comment - this is part of a larger project where I read the last line of a file, in which the dates and times are expressed in datevec form and to which new, processed data will eventually be appended. It just seems easier to work with the datvec format, particularly as it's easier to do said processing by looking up specific values in the datevec columns. It's also easier to view the datevec data and check that code is working as expected and not potentially causing problems further down the processing pipeline, just as I did with the original problem.
Upvotes: 0
Reputation: 22245
There is no 'drift'. It's just that at some point your 20 minute interval starts getting expressed as 19 minutes and 60 seconds (=20 minutes).
I don't know why, but in theory the two are equivalent and you should not care about it. If you are worried about 'formatting' the date to obtain an output that is more visually meaningful, use a formatting function. E.g. datestr(s)
will give you what you expect.
PS: "20 minutes expressed as fraction of a 24h-day" is as simple 20 / 24 / 60
. No real need for the first line.
Upvotes: 1