Problems trying to find fakes dates.

1 回表示 (過去 30 日間)
Claudio Iturra
Claudio Iturra 2023 年 1 月 11 日
回答済み: Eric Sofen 2023 年 1 月 26 日
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 件のコメント
Claudio Iturra
Claudio Iturra 2023 年 1 月 11 日
編集済み: Claudio Iturra 2023 年 1 月 11 日
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!
Claudio Iturra
Claudio Iturra 2023 年 1 月 11 日
......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

サインインしてコメントする。

回答 (2 件)

the cyclist
the cyclist 2023 年 1 月 11 日
編集済み: the cyclist 2023 年 1 月 11 日
As recommended there, and many other places in the documentation, use of the newer datetime data type is encouraged.
  2 件のコメント
Claudio Iturra
Claudio Iturra 2023 年 1 月 11 日
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
the cyclist
the cyclist 2023 年 1 月 11 日
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

サインインしてコメントする。


Eric Sofen
Eric Sofen 2023 年 1 月 26 日
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!

カテゴリ

Help Center および File ExchangeDates and Time についてさらに検索

タグ

製品


リリース

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by