Datevec does not know leap years

I imported a csv file from Excel with dates. datevec transfers the number into human readable dates except it does stumble over (some) leap years! 29 February simply becomes 1 March! This happens for 2000 and 2016 but not 2008 and 2012 (2004 had no observation on the 29th).

Octave 6.4.0 on MacOS 12.1

I went to octave-online.net to access 6.4.0 and tried commands like this for leap years:
datevec (datenum ([2012 2 29]))
They all give the same dates back.

@posterNo7: Could you share what command you used to convert the dates? If you can provide a minimum example that would be helpful.

I’ve tried it and all the prompts are well


for year = 2000:2022
disp(datevec(datenum([year 2 29])));
endfor

2000 2 29 0 0 0
2001 3 1 0 0 0
2002 3 1 0 0 0
2003 3 1 0 0 0
2004 2 29 0 0 0
2005 3 1 0 0 0
2006 3 1 0 0 0
2007 3 1 0 0 0
2008 2 29 0 0 0
2009 3 1 0 0 0
2010 3 1 0 0 0
2011 3 1 0 0 0
2012 2 29 0 0 0
2013 3 1 0 0 0
2014 3 1 0 0 0
2015 3 1 0 0 0
2016 2 29 0 0 0
2017 3 1 0 0 0
2018 3 1 0 0 0
2019 3 1 0 0 0
2020 2 29 0 0 0
2021 3 1 0 0 0
2022 3 1 0 0 0

1 Like

Yes, sorry, should have been part of the original post.

Say, in Excel I have three dates:
28/02/2000
29/02/2000
01/03/2000
These get exported as
36584
36585
36586

In Octave datevec(36584) returns
100.00 2.00 28.00 0 0 0
as desired. But datevec(36585) returns
100.00 3.00 1.00 0 0 0
which is wrong.

I have also now checked Matlab and the same thing happens. R, in contrast, gets it right:

as.Date(36584, origin = “1899-12-30”)
[1] “2000-02-28”
as.Date(36585, origin = “1899-12-30”)
[1] “2000-02-29”
as.Date(36586, origin = “1899-12-30”)
[1] “2000-03-01”

The year 2000 was a leap year. The year 100 was not.
You’d need to add the correct offset before calling datevec.

To expand on what @mmuetzel said, here are the date numbers for those dates, in 6.4.0:

octave:1> datenum([2000 2 28])
ans = 730544
octave:2> datenum([2000 2 29])
ans = 730545
octave:3> datenum([2000 3 1])
ans = 730546

This is using a different starting date than Excel, so the offset will be 730544 - 36584 = 693960. If you add that offset to all your Excel date numbers, it’ll come out OK. Please test and let us know.

1 Like

I get now what’s going on. I would, however, argue that the documentation is quite misleading.
Help datevec includes “If not specified, it defaults to the current year minus 50.” It seems natural to assume that this would be true here too even though it apparently is not. Compare that to the corresponding R help output, which is quite enlightening.
Anyway, thanks for your help! I guess the thread can be closed.

I think the 50 year rule applies only to 2-digit years in string formats, not to vector inputs.

octave:1> datevec("12/25/20")
ans =

   2020     12     25      0      0      0

octave:2> datevec("12/25/90")
ans =

   1990     12     25      0      0    

octave:3> datevec("12/25/70")
ans =

   2070     12     25      0      0    

It tries to guess the string format when it’s not specified, but it’s not foolproof. That guessing is not even done for a vector input though, or a datenum input with a different starting date.

Edit: If you have an idea for making that help text clearer, please propose a documentation patch if you can.