How to check if a given Date exists in DART?
Solution 1
You can convert parsed date to string with original format and then compare if it's matching the input.
void main() {
var inputs = ['20180101', // -> 2018-01-01 00:00:00.000
'20181231', // -> 2018-12-31 00:00:00.000
'20180230', // -> 2018-03-02 00:00:00.000
'20181301', // -> 2019-01-01 00:00:00.000
'20181364'];// -> 2019-03-05 00:00:00.000
inputs.forEach((input) {
print("$input is valid string: ${isValidDate(input)}");
});
}
bool isValidDate(String input) {
final date = DateTime.parse(input);
final originalFormatString = toOriginalFormatString(date);
return input == originalFormatString;
}
String toOriginalFormatString(DateTime dateTime) {
final y = dateTime.year.toString().padLeft(4, '0');
final m = dateTime.month.toString().padLeft(2, '0');
final d = dateTime.day.toString().padLeft(2, '0');
return "$y$m$d";
}
Solution 2
My solution to validate the birthday was this, we can see that it has the leap year calculation.
class DateHelper{
/*
* Is valid date and format
*
* Format: dd/MM/yyyy
* valid:
* 01/12/1996
* invalid:
* 01/13/1996
*
* Format: MM/dd/yyyy
* valid:
* 12/01/1996
* invalid
* 13/01/1996
* */
static bool isValidDateBirth(String date, String format) {
try {
int day, month, year;
//Get separator data 10/10/2020, 2020-10-10, 10.10.2020
String separator = RegExp("([-/.])").firstMatch(date).group(0)[0];
//Split by separator [mm, dd, yyyy]
var frSplit = format.split(separator);
//Split by separtor [10, 10, 2020]
var dtSplit = date.split(separator);
for (int i = 0; i < frSplit.length; i++) {
var frm = frSplit[i].toLowerCase();
var vl = dtSplit[i];
if (frm == "dd")
day = int.parse(vl);
else if (frm == "mm")
month = int.parse(vl);
else if (frm == "yyyy")
year = int.parse(vl);
}
//First date check
//The dart does not throw an exception for invalid date.
var now = DateTime.now();
if(month > 12 || month < 1 || day < 1 || day > daysInMonth(month, year) || year < 1810 || (year > now.year && day > now.day && month > now.month))
throw Exception("Date birth invalid.");
return true;
} catch (e) {
return false;
}
}
static int daysInMonth(int month, int year) {
int days = 28 + (month + (month/8).floor()) % 2 + 2 % month + 2 * (1/month).floor();
return (isLeapYear(year) && month == 2)? 29 : days;
}
static bool isLeapYear(int year)
=> (( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 );
}
Solution 3
Support for validating dates was added for dart in December 2020: https://pub.dev/documentation/intl/latest/intl/DateFormat/parseStrict.html
Max
Updated on December 12, 2022Comments
-
Max over 1 year
If you pass a non-existing/non-real date like: '20181364' (2018/13/64) into DateTime (constructor or parse-method), no exception is thrown. Instead a calculated DateTime is returned.
Example: '20181364' --> 2019-03-05 00:00:00.000
How can I check if a given date really exists/is valid?
I tried to solve this using DartPad (without success), so no Flutter doctor output required here.
void main() { var inputs = ['20180101', // -> 2018-01-01 00:00:00.000 '20181231', // -> 2018-12-31 00:00:00.000 '20180230', // -> 2018-03-02 00:00:00.000 '20181301', // -> 2019-01-01 00:00:00.000 '20181364'];// -> 2019-03-05 00:00:00.000 inputs.forEach((input) => print(convertToDate(input))); } String convertToDate(String input){ return DateTime.parse(input).toString(); }
It would be great if there exist some kind of method to check if a given date really exists/is valid, e.g.:
- a validate function in DateTime
- another lib that does not use DateTime.parse() for validation
How would you solve this?
-
jdixon04 almost 5 yearsFor others, this seems to be an issue that's tracked and is still open in the dartlang repo: github.com/dart-lang/sdk/issues/11189
-
jdixon04 almost 5 yearsinteresting approach!
-
Max almost 5 yearsTotally agree, nice and clean approach :) Thank you :)
-
easeccy about 2 yearsThis should be the accepted answer.