Problems trying to find fakes dates.

idx =
2005 2 28 18 0 0
2005 2 28 19 0 0
2005 2 28 20 0 0
2005 2 28 21 0 0
2005 2 28 22 0 0
2005 2 28 23 0 0
2005 3 1 0 0 0
2005 3 1 1 0 0
2005 3 1 2 0 0
>> time = datenum(idx)
time =
732371.75
732371.791666667
732371.833333333
732371.875
732371.916666667
732371.958333333
732372
732372.041666667
732372.083333333
% looking for a date that is in the domain
>> find(time == datenum(2005,2,28,18,0,0))
ans =
1
% looking for a date that is NOT in the domain
>> find(time == datenum(2005,2,29,0,0,0))
ans =
7
% the output shuld be 0×1 empty double column vector.
% Why when u try to find fakes dates, the output is a value of an existing date in the domain?

3 Kommentare

Good question. I remember using this trick to check if a year is a leap year.
I bet there is a rational for this. It could also be implented to report error if date inputs are "out of range".
datenum(2004,2,29)==datenum(2004,3,1)
ans = logical
0
datenum(2005,2,29)==datenum(2005,3,1)
ans = logical
1
datenum(2005,3,32)==datenum(2005,4,1)
ans = logical
1
Claudio Iturra
Claudio Iturra am 11 Jan. 2023
Bearbeitet: Claudio Iturra am 11 Jan. 2023
Hi Fangjun, Thanks! I already add a line to my code that verify ramdoms date...basically, I'm evaluating parameters in the ocean during ramdon dates, but becouse Im stupid, I forget to add a line that controls february's days, thinking that the find(time==datenum()) will did not take fakes dates. Actually the code found those fakes dates during february and did not sent me any error, I just was cheking for bad dates and eventually found that! Maybe datenum needs to verify in some way corrects dates.
Big question here is if 2 elemets are not the same, why the find code sent you the closer one..
find(time == datenum(2005,2,29,0,0,0))
find(x == y)
(x == y)
Have a great day!
......mmmmmm
find(time == datenum(2005,45,29,0,0,0)) %month 45 of the year 2005!
ans =
59112
>> datevec(time(59112))
ans =
2008 9 29 0 0 0

Melden Sie sich an, um zu kommentieren.

Antworten (2)

the cyclist
the cyclist am 11 Jan. 2023
Bearbeitet: the cyclist am 11 Jan. 2023

1 Stimme

As recommended there, and many other places in the documentation, use of the newer datetime data type is encouraged.

2 Kommentare

Hi, Same behavior using datetime....
%Same behavior using datetime
idx =
2005 2 28 18 0 0
2005 2 28 19 0 0
2005 2 28 20 0 0
2005 2 28 21 0 0
2005 2 28 22 0 0
2005 2 28 23 0 0
2005 3 1 0 0 0
2005 3 1 1 0 0
2005 3 1 2 0 0
>> time = datetime(idx)
time =
9×1 datetime array
28-Feb-2005 18:00:00
28-Feb-2005 19:00:00
28-Feb-2005 20:00:00
28-Feb-2005 21:00:00
28-Feb-2005 22:00:00
28-Feb-2005 23:00:00
01-Mar-2005 00:00:00
01-Mar-2005 01:00:00
01-Mar-2005 02:00:00
>> find(time == datetime(2005,2,29,0,0,0)) %fake date
ans =
7
Sorry, I should not have implied that using datetime would solve the carryover issue. datetime also implement the carryover algorithm discussed on that page.
I did some searching, and did not find a definitve date validation method in MATLAB. The topic has come up a few times in this forum. It seems to me that this thread is your best bet, which seems to have settled on this code:
function valid = valid_date(year, month, date)
if(nargin ~= 3)
valid = false;
elseif ((~isscalar(year)||(mod(year,1)~=0) || year<0))
valid = false;
elseif ((~isscalar(month))||(mod(month,1)~=0) || (month<=0) || (month>12))
valid = false;
elseif ((~isscalar(date))||(mod(date,1)~=0) || (date<=0))
valid = false;
elseif(any(month==[1:2:7,8:2:12])&& date>31)
valid = false;
elseif (any(month==[4,6,9,11]) && date>30)
valid = false;
elseif month==2 && date>(28+(mod(year,400)==0 || (mod(year,100)~=0 && mod(year,4)==0)))
valid=false;
else
valid = true;
end

Melden Sie sich an, um zu kommentieren.

Eric Sofen
Eric Sofen am 26 Jan. 2023

0 Stimmen

The reason datetime(2005,2,29) works is that we want to support constructing a vector of datetimes:
datetime(2023,1,1:100)
ans = 1×100 datetime array
01-Jan-2023 02-Jan-2023 03-Jan-2023 04-Jan-2023 05-Jan-2023 06-Jan-2023 07-Jan-2023 08-Jan-2023 09-Jan-2023 10-Jan-2023 11-Jan-2023 12-Jan-2023 13-Jan-2023 14-Jan-2023 15-Jan-2023 16-Jan-2023 17-Jan-2023 18-Jan-2023 19-Jan-2023 20-Jan-2023 21-Jan-2023 22-Jan-2023 23-Jan-2023 24-Jan-2023 25-Jan-2023 26-Jan-2023 27-Jan-2023 28-Jan-2023 29-Jan-2023 30-Jan-2023 31-Jan-2023 01-Feb-2023 02-Feb-2023 03-Feb-2023 04-Feb-2023 05-Feb-2023 06-Feb-2023 07-Feb-2023 08-Feb-2023 09-Feb-2023 10-Feb-2023 11-Feb-2023 12-Feb-2023 13-Feb-2023 14-Feb-2023 15-Feb-2023 16-Feb-2023 17-Feb-2023 18-Feb-2023 19-Feb-2023 20-Feb-2023 21-Feb-2023 22-Feb-2023 23-Feb-2023 24-Feb-2023 25-Feb-2023 26-Feb-2023 27-Feb-2023 28-Feb-2023 01-Mar-2023 02-Mar-2023 03-Mar-2023 04-Mar-2023 05-Mar-2023 06-Mar-2023 07-Mar-2023 08-Mar-2023 09-Mar-2023 10-Mar-2023 11-Mar-2023 12-Mar-2023 13-Mar-2023 14-Mar-2023 15-Mar-2023 16-Mar-2023 17-Mar-2023 18-Mar-2023 19-Mar-2023 20-Mar-2023 21-Mar-2023 22-Mar-2023 23-Mar-2023 24-Mar-2023 25-Mar-2023 26-Mar-2023 27-Mar-2023 28-Mar-2023 29-Mar-2023 30-Mar-2023 31-Mar-2023 01-Apr-2023 02-Apr-2023 03-Apr-2023 04-Apr-2023 05-Apr-2023 06-Apr-2023 07-Apr-2023 08-Apr-2023 09-Apr-2023 10-Apr-2023
Note that this is only for constructing datetime from numeric inputs. For text timestamps, it needs to be a valid date/time on the calendar:
% This errors:
% datetime("2005-02-29")
% Error using datetime
% Could not recognize the date/time format of '2005-02-29'. You can specify a format using the 'InputFormat' parameter. If the date/time text contains day, month, or time zone names in a language foreign to the 'en_US' locale, those might not be recognized. You can specify a different locale using the 'Locale' parameter.
In your actual workflow, do you have access to the original Y/M/D data before constructing a datetime from it? If so, you could compare the month/day resulting from constructing the datetime to the original to check for spurious data with values that datetime wrapped to the next month:
ymd = [2005 2 28; 2005 2 29; 2005 3 1]
ymd = 3×3
2005 2 28 2005 2 29 2005 3 1
d = datetime(ymd);
find(d.Month == ymd(:,2))
ans = 2×1
1 3
I'd be hesitant to construct a full date validation scheme as @the cyclist laid out. Yes, it's doable, but many over the years have fallen into various traps around leap years and Daylight Saving Time!

Kategorien

Produkte

Version

R2022a

Tags

Gefragt:

am 11 Jan. 2023

Beantwortet:

am 26 Jan. 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by