Ivanius
Ivanius

Reputation: 109

How to make age validation in flutter

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?

Upvotes: 9

Views: 19146

Answers (8)

Boken
Boken

Reputation: 5362

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 || 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);
}

Upvotes: 18

Sam
Sam

Reputation: 11

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

Upvotes: 0

Zahid Tekbaş
Zahid Tekbaş

Reputation: 941

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);}

Upvotes: 0

Alex Hartford
Alex Hartford

Reputation: 6000

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.

Upvotes: 1

Ayesha Iftikhar
Ayesha Iftikhar

Reputation: 400

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")
)

Upvotes: 0

Farzana Rahman
Farzana Rahman

Reputation: 1

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"),
    );
  }
}

Upvotes: 0

Sanket Vekariya
Sanket Vekariya

Reputation: 2956

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. :)

Upvotes: 3

Viren V Varasadiya
Viren V Varasadiya

Reputation: 27177

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);

Upvotes: 0

Related Questions