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;
}
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, 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
}
or if you want to implement your own rule:
/// Converts a two-digit year to a full year.
///
/// The returned year will be within `lookBehindYears` (exclusive)
/// before the current year and `100 - lookBehindYears` (inclusive) after
/// the current year.
int fromTwoDigitYear(int twoDigitYear, {int lookBehindYears = 80}) {
assert(twoDigitYear >= 0);
assert(twoDigitYear < 100);
assert(lookBehindYears >= 0);
assert(lookBehindYears < 100);
var thisYear = DateTime.now().year;
var thisCentury = (thisYear ~/ 100) * 100;
var treatAsEarlier =
twoDigitYear > (thisYear % 100 + (100 - lookBehindYears));
return thisCentury + twoDigitYear + (treatAsEarlier ? -100 : 0);
}
void main() {
// Printed output from the year 2023.
print(fromTwoDigitYear(0)); // Prints: 2000
print(fromTwoDigitYear(99)); // Prints: 1999
print(fromTwoDigitYear(85)); // Prints: 1985
print(fromTwoDigitYear(30)); // Prints: 2030
print(fromTwoDigitYear(40)); // Prints: 2040
print(fromTwoDigitYear(42)); // Prints: 2042
print(fromTwoDigitYear(43)); // Prints: 2043
print(fromTwoDigitYear(44)); // Prints: 1944
}