skip to Main Content

am new to flutter, in my project am scanning passport MRZ line using google ml kit and parse the data.

Am facing issue when user birthdate is 23-04-2000 , in this case MRZ will be 000423.

and I trying to convert to dd-MM-yyyy format facing issue.

Please help 🙂

I tried below code by using

String convertMrzDate(String dateStr) {
  String year = dateStr.substring(0, 2);
  String month = dateStr.substring(2, 4);
  String day = dateStr.substring(4, 6);

  int currentYear = DateTime.now().year;
  int currentTwoDigitYear = currentYear % 100;

  int twoDigitYear = int.parse(year);
  int century = (currentYear ~/ 100) * 100;

  int centuryAdjustedYear;
  if (twoDigitYear <= currentTwoDigitYear) {
    centuryAdjustedYear = century + twoDigitYear;
  } else {
    centuryAdjustedYear = century - 100 + twoDigitYear;
  }

  String formattedDate = '$centuryAdjustedYear-$month-$day';
  return formattedDate;
}

it is working for birthdate but expiry date getting wrong data.

My Java Code

 public  static String convertMrzDate(String dateStr) throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd", Locale.ENGLISH);
    Date d1 = sdf.parse(dateStr);
    sdf.applyPattern("yyyy-MM-dd");
    return sdf.format(d1);
}

I tried below dart code using plugin:intl
but getting error

Trying to read MM from 000423 at position 6

    String convertMrzDate(String dateStr) {
  final inputFormat = DateFormat('yyMMdd', 'en_US');
  final outputFormat = DateFormat('yyyy-MM-dd');

  final date = inputFormat.parse(dateStr);
  final formattedDate = outputFormat.format(date);

  return formattedDate;
}

2

Answers


  1. Use the add x if greater than, that should fix most of the year errors, the check does not rely on the YY-- part of the year so you can’t know for sure only locking at that string.

    DateTime? mzt_parse_date(String date, String check) {
      final cut_year = 69;  // Same as MySQL
      final exp_date = date.replaceAll('<', '0');
      
      final check_nums = [7, 3, 1, 7, 3, 1];
      final date_chars = exp_date.split('');
      assert(date_chars.length == check_nums.length);
    
      var sum = 0;
      for (var i = 0; i < date_chars.length; i++) {
        sum += int.parse(date_chars[i]) * check_nums[i];
      }
    
      if (sum % 10 == int.parse(check)) {
        final year = int.parse(exp_date.substring(0, 2));
        return DateTime(
          year + ((year < cut_year) ? 2000 : 1900),
          int.parse(exp_date.substring(2, 4)),
          int.parse(exp_date.substring(4, 6)),
        );
      }
    }
    

    To get a dd-mm-yyyy for you can do the same thing as you did in this line, but backwords.

    String formattedDate = '$centuryAdjustedYear-$month-$day';
    

    Or use the Datetime type.

    String date_to_ddmmyyyy(DateTime date) {
      return '${date.day}-${date.month}-${date.year}';
    }
    
    Login or Signup to reply.
  2. You currently do:

    if (twoDigitYear <= currentTwoDigitYear) {
      centuryAdjustedYear = century + twoDigitYear;
    } else {
      centuryAdjustedYear = century - 100 + twoDigitYear;
    }
    

    so any year in the future will be treated as being from the 1900s. That won’t work for expiration dates, which usually would be in the near future.

    You instead should use something like the -80/+20 rule that DateFormat from package:intl uses. If you want to re-use DateFormat‘s existing logic (which I recommend that you do; the logic is not trivial), just reformat your original String to include delimiters, and then you can use DateFormat.parse directly:

    import 'package:intl/intl.dart';
    
    String convertMrzDate(String dateStr) {
      String year = dateStr.substring(0, 2);
      String month = dateStr.substring(2, 4);
      String day = dateStr.substring(4, 6);
    
      var delimited = '$year-$month-$day';
      var dateTime = DateFormat('yy-MM-dd').parse(delimited);
      return DateFormat('dd-MM-yyyy').format(dateTime);
    }
    
    
    void main() {
      print(convertMrzDate('000423')); // Prints: 23-04-2000
      print(convertMrzDate('241031')); // Prints: 31-10-2024
      print(convertMrzDate('991031')); // Prints: 31-10-1999
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search