Flutter面临护照MRZ 2位数年份代码的问题

vsikbqxv  于 2023-05-18  发布在  Flutter
关注(0)|答案(2)|浏览(104)

我是新来的Flutter,在我的项目我扫描护照MRZ线使用谷歌毫升套件和解析数据。
当用户出生日期为2000年4月23日时,我面临问题,在这种情况下,MRZ将为000423。
我试图转换到dd-MM-yyyy格式面临的问题。
请帮帮忙:)
我尝试下面的代码通过使用

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

它正在为出生日期工作,但到期日期得到错误的数据。
我的Java代码

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

我尝试使用plugin:intl在下面的dart代码中运行,但出现错误
尝试从位置6的000423读取MM

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

guicsvcw1#

您目前正在执行以下操作:

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

所以未来的任何一年都会被认为是20世纪的。这对到期日不起作用,到期日通常是在不久的将来。
相反,您应该使用类似DateFormat from package:intl使用的-80/+20规则。如果你想重用DateFormat的现有逻辑,只需重新格式化你原来的String,使其包含分隔符,然后你就可以直接使用DateFormat.parse了:

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
}

或者如果你想实现你自己的规则:

/// 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
}
6psbrbz9

6psbrbz92#

使用 add x if greater than,这应该可以修复大多数年份错误,检查不依赖于年份的 YY-- 部分,因此您无法确定是否只锁定该字符串。

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

要获得dd-mm-yyyy,您可以执行与在这一行中所做的相同的操作,但需要backwords。

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

或者使用Datetime类型。

String date_to_ddmmyyyy(DateTime date) {
  return '${date.day}-${date.month}-${date.year}';
}

相关问题