I posted this function on
this topic. Thought to post here as it might be useful for someone.
EDIT : If you're looking for a function that accepts any date-format and separator -
http://forum.sa-mp.com/showpost.php?...postcount=4616
First version :
IsValidDate - Function returns
true if the given date is valid,
false if invalid.
Parameters
dStr - Date as string.
delim - Date separator. By default, it's '
/'.
dFormat - Date format. By default, it's "ymd" (YYYY/MM/DD). (y = year, m = month, d = day)
size - Size of dStr (by default).
pawn Код:
stock bool:isValidDate(dStr[], delim = '/', dFormat[] = "ymd", size = sizeof(dStr)) {
new
monthDays[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
},
temp_Year,
temp_Month,
temp_Day,
temp_Index = 0,
temp_Pos = 0,
temp_ePos = 0,
temp_shortStr[5]
;
do {
while(dStr[temp_ePos] != delim) {
if(++temp_ePos >= size) {
temp_ePos = size - 1;
break;
}
}
strmid(temp_shortStr, dStr, temp_Pos, temp_ePos, sizeof(temp_shortStr));
temp_Pos = ++temp_ePos;
switch(dFormat[temp_Index++]) {
case 'm', 'M':
temp_Month = strval(temp_shortStr);
case 'd', 'D':
temp_Day = strval(temp_shortStr);
case 'y', 'Y':
temp_Year = strval(temp_shortStr);
default:
return false;
}
}
while(temp_Index < 3);
if((temp_Year % 400) == 0 || ((temp_Year % 100) != 0 && (temp_Year % 4) == 0))
monthDays[1] = 29;
if(temp_Month < 1 || temp_Month > 12)
return false;
if(temp_Day < 1 || temp_Day > monthDays[temp_Month - 1])
return false;
return true;
}
Example code:
pawn Код:
public OnFilterScriptInit() {
new date[15] = "06/29/2016"; //MM/DD/YYYY "mdy"
printf("IsValid : %d", isValidDate(date, '/', "mdy"));
date = "29/02/2016"; //DD/MM/YYYY "dmy"
printf("IsValid : %d", isValidDate(date, '/', "dmy"));
date = "2016/02/29"; //YYYY/MM/DD "ymd"
printf("IsValid : %d", isValidDate(date, '/', "ymd"));
//invalid tests.
//February doesn't have 29 days in 2017. So the further results should be 0.
date = "02/29/2017"; //MM/DD/YYYY "mdy"
printf("IsValid : %d", isValidDate(date, '/', "mdy"));
date = "29/02/2017"; //DD/MM/YYYY "dmy"
printf("IsValid : %d", isValidDate(date, '/', "dmy"));
date = "2017/02/29"; //YYYY/MM/DD "ymd"
printf("IsValid : %d", isValidDate(date, '/', "ymd"));
date = "01/32/2016"; //MM/DD/YYYY "mdy" //January doesn't have 32 days.
printf("IsValid : %d", isValidDate(date, '/', "mdy"));
return 1;
}
Second version :
This works similar to the first one, except that it does not have a delimiter parameter. It works with any separator, only the date-format has to be mentioned if it's different from YYYY/MM/DD.
pawn Код:
stock bool:isValidDate(dStr[], dFormat[] = "ymd", size = sizeof(dStr)) {
new
monthDays[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
},
temp_Year,
temp_Month,
temp_Day,
temp_Index = 0,
temp_Pos = 0,
temp_ePos = 0,
temp_shortStr[5]
;
do {
while(dStr[temp_ePos] >= 48 && dStr[temp_ePos] <= 57) {
if(++temp_ePos >= size) {
temp_ePos = size - 1;
break;
}
}
strmid(temp_shortStr, dStr, temp_Pos, temp_ePos, sizeof(temp_shortStr));
temp_Pos = ++temp_ePos;
switch(dFormat[temp_Index++]) {
case 'm', 'M':
temp_Month = strval(temp_shortStr);
case 'd', 'D':
temp_Day = strval(temp_shortStr);
case 'y', 'Y':
temp_Year = strval(temp_shortStr);
default:
return false;
}
}
while(temp_Index < 3);
if((temp_Year % 400) == 0 || ((temp_Year % 100) != 0 && (temp_Year % 4) == 0))
monthDays[1] = 29;
if(temp_Month < 1 || temp_Month > 12)
return false;
if(temp_Day < 1 || temp_Day > monthDays[temp_Month - 1])
return false;
return true;
}
Example for second version:
pawn Код:
//I'm testing on different date separators.
new date[15] = "06.29.2016"; //MM/DD/YYYY "mdy"
printf("IsValid : %d", isValidDate(date, "mdy"));
date = "29/02/2016"; //DD/MM/YYYY "dmy"
printf("IsValid : %d", isValidDate(date, "dmy"));
date = "2016-02-29"; //YYYY/MM/DD "ymd"
printf("IsValid : %d", isValidDate(date, "ymd"));
//invalid tests.
//February doesn't have 29 days in 2017. So the further results should be 0.
date = "02>29>2017"; //MM/DD/YYYY "mdy"
printf("IsValid : %d", isValidDate(date, "mdy"));
date = "29!02!2017"; //DD/MM/YYYY "dmy"
printf("IsValid : %d", isValidDate(date, "dmy"));
date = "2017\02\29"; //YYYY/MM/DD "ymd"
printf("IsValid : %d", isValidDate(date, "ymd"));
date = "01~32~2016"; //MM/DD/YYYY "mdy" //January doesn't have 32 days.
printf("IsValid : %d", isValidDate(date, "mdy"));
Output - of both first and second version:
Код:
IsValid : 1
IsValid : 1
IsValid : 1
IsValid : 0
IsValid : 0
IsValid : 0
IsValid : 0