My goal is to check users age by entered birthday and return error if user is not 18 years old or older. But i have no idea how to do that. Date format is "dd-MM-yyyy". Any ideas how to do that?
-
in which formate you have date? I mean i String or DateTime object? – Viren V Varasadiya Apr 16 '20 at 12:11
-
i'm using String format – Ivanius Apr 16 '20 at 12:17
-
What have you tried for it? – Ravindra Kushwaha Apr 16 '20 at 12:35
-
@Ivanius is my solution working? – Boken May 18 '20 at 00:28
-
Yeah. Thank you so much for your support! – Ivanius May 20 '20 at 19:38
8 Answers
Package
To easily parse date we need package intl
:
https://pub.dev/packages/intl#-installing-tab-
So add this dependency to youd pubspec.yaml
file (and get
new dependencies)
Solution #1
You can just simple compare years:
bool isAdult(String birthDateString) {
String datePattern = "dd-MM-yyyy";
DateTime birthDate = DateFormat(datePattern).parse(birthDateString);
DateTime today = DateTime.now();
int yearDiff = today.year - birthDate.year;
int monthDiff = today.month - birthDate.month;
int dayDiff = today.day - birthDate.day;
return yearDiff > 18 || yearDiff == 18 && monthDiff >= 0 && dayDiff >= 0;
}
But it's not always true, because to the end of current year you are "not adult".
Solution #2
So better solution is move birth day 18 ahead and compare with current date.
bool isAdult2(String birthDateString) {
String datePattern = "dd-MM-yyyy";
// Current time - at this moment
DateTime today = DateTime.now();
// Parsed date to check
DateTime birthDate = DateFormat(datePattern).parse(birthDateString);
// Date to check but moved 18 years ahead
DateTime adultDate = DateTime(
birthDate.year + 18,
birthDate.month,
birthDate.day,
);
return adultDate.isBefore(today);
}
-
-
1Also there second error in solution #2: it should be today.isBefore(adultDate) – Vytautas Pranskunas Mar 05 '21 at 09:24
-
solution #1 is wrong for `today=DateTime (2021-05-04 00:00:00.000000)` and `birthDate =DateTime (2003-04-05 00:00:00.000000)` in this case `dayDiff=-1` that returns `false` but should return `true` – Yauheni Pakala May 03 '21 at 21:56
-
these solutions are not true! first one must return this : return yearDiff > 18 || yearDiff == 18 && monthDiff > 0 || yearDiff == 18 && monthDiff == 0 && dayDiff >= 0; – Nastaran Mohammadi Aug 25 '21 at 07:04
The best age validation I have ever come up with is based on Regex.
The below logic covers all the breakpoint related age.
// regex for validation of date format : dd.mm.yyyy, dd/mm/yyyy, dd-mm-yyyy
RegExp regExp = new RegExp(
r"^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$",
caseSensitive: true,
multiLine: false,
);
//method to calculate age on Today (in years)
int ageCalculate(String input){
if(regExp.hasMatch(input)){
DateTime _dateTime = DateTime(
int.parse(input.substring(6)),
int.parse(input.substring(3, 5)),
int.parse(input.substring(0, 2)),
);
return DateTime.fromMillisecondsSinceEpoch(
DateTime.now().difference(_dateTime).inMilliseconds)
.year -
1970;
} else{
return -1;
}
}
void main() {
// input values and validations examples
var input = "29.02.2008";
print("12.13.2029 : " + regExp.hasMatch("12.13.2029").toString());
print("29.02.2028 : " + regExp.hasMatch("29.02.2028").toString());
print("29.02.2029 : " + regExp.hasMatch("29.02.2029").toString());
print("11/12-2019 : " + regExp.hasMatch("11/12-2019").toString());
print("23/12/2029 : " + regExp.hasMatch("23/12/2029").toString());
print("23/12/2029 : " + regExp.hasMatch(input).toString());
print("sdssh : " + regExp.stringMatch("sdssh").toString());
print("age as per 29.02.2008 : " + ageCalculate(input).toString());
}
Output
12.13.2029 : false
29.02.2028 : true
29.02.2029 : false
11/12-2019 : false
23/12/2029 : true
23/12/2029 : true
sdssh : null
age as per 29.02.2008 : 12
I hope you will find this useful. :)

- 2,848
- 3
- 12
- 34
You can use an extension to add a function that checks this to DateTime. For example:
extension DateTimeX on DateTime {
bool isUnderage() =>
(DateTime(DateTime.now().year, this.month, this.day)
.isAfter(DateTime.now())
? DateTime.now().year - this.year - 1
: DateTime.now().year - this.year) < 18;
}
void main() {
final today = DateTime.now();
final seventeenY = DateTime(today.year - 18, today.month, today.day + 1);
final eighteenY = DateTime(today.year - 18, today.month, today.day);
print(today.isUnderage());
print(seventeenY.isUnderage());
print(eighteenY.isUnderage());
}
It's worth noting this doesn't require intl
or any other external package. Paste this right into dartpad.dev to test it out.

- 5,110
- 2
- 19
- 36
You can find year difference in following way.
String _data = '16-04-2000';
DateTime _dateTime = DateTime(
int.parse(_data.substring(6)),
int.parse(_data.substring(3, 5)),
int.parse(_data.substring(0, 2)),
);
int yeardiff = DateTime.fromMillisecondsSinceEpoch(
DateTime.now().difference(_dateTime).inMilliseconds)
.year -
1970;
print(yeardiff);

- 25,492
- 9
- 45
- 61
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Home(),
);
}
}
class Home extends StatefulWidget {
Home({Key key}) : super(key: key);
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
String dateFormate;
@override
Widget build(BuildContext context) {
var dateNow = new DateTime.now();
var givenDate = "1969-07-20";
var givenDateFormat = DateTime.parse(givenDate);
var diff = dateNow.difference(givenDateFormat);
var year = ((diff.inDays)/365).round();
return Container(
child: (year < 18)?Text('You are under 18'):Text("$year years old"),
);
}
}

- 1
- 1
-
-
I think `floor()` should be used instead of `round()`. `var year = ((diff.inDays)/365).floor();` – AlvaroSantisteban Oct 27 '22 at 15:47
It is quite simple if you are using intl package. Be sure you have set the same format for your date picker and the function in which you are validating the age.
You can use the following code for calculating the difference between today's date and entered date:
double isAdult(String enteredAge) {
var birthDate = DateFormat('MMMM d, yyyy').parse(enteredAge);
print("set state: $birthDate");
var today = DateTime.now();
final difference = today.difference(birthDate).inDays;
print(difference);
final year = difference / 365;
print(year);
return year;
}
And the you can create a condition on the returned value of the function like:
Container(
child: (isAdult(selecteddate) < 18 ? Text("You are under age") : Text("$selecteddate is your current age")
)

- 358
- 3
- 13
There are 6570 days in 18 years. So I created a simple operation to check if entered date is greater than 6570 days comparing to difference of today's date.
DateTime.now().difference(date) < Duration(days: 6570)
if this is true, then user is younger than 18 years old, if it is not, then user is older than 18 years old. Works on days too.
This is my if blocks:
if (DateTime.now().difference(date) < Duration(days: 6570)) {
EasyLoading.showError('You should be 18 years old to register');}
else {
store.changeBirthday(date);}

- 809
- 2
- 12
- 27
import 'package:intl/intl.dart';
void main() {
print(_isAdult('12-19-2004') ? 'over 18' : 'under 18');
}
bool _isAdult(String dob) {
final dateOfBirth = DateFormat("MM-dd-yyyy").parse(dob);
final now = DateTime.now();
final eighteenYearsAgo = DateTime(
now.year - 18,
now.month,
now.day + 1, // add day to return true on birthday
);
return dateOfBirth.isBefore(eighteenYearsAgo);
}
Similar to @Broken's accepted answer but I think this is more readable.
Test on DartPad https://dartpad.dev/?id=53885d812c90230f2a5b786e75b6cd82

- 11
- 2