英文:
Flutter facing issue with passport MRZ 2 digit year code
问题
I understand your request. Here's the translated code:
我刚接触Flutter,在我的项目中,我使用Google ML Kit扫描护照MRZ行并解析数据。
当用户的出生日期是23-04-2000时,MRZ将是000423。
我尝试将其转换为dd-MM-yyyy格式时遇到问题。
请帮助 :)
我尝试以下代码:
```dart
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);
}
我尝试以下Dart代码,使用了intl
插件,但出现错误。
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;
}
希望这可以帮助解决您的问题。
<details>
<summary>英文:</summary>
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;
}
</details>
# 答案1
**得分**: 1
你目前正在执行以下操作:
```dart
if (twoDigitYear <= currentTwoDigitYear) {
centuryAdjustedYear = century + twoDigitYear;
} else {
centuryAdjustedYear = century - 100 + twoDigitYear;
}
因此,将来的任何年份都将被视为来自1900年代。 这对于通常位于不久的将来的到期日期不起作用。
相反,你应该使用类似 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);
}
或者,如果要实现自己的规则:
/// 将两位数年份转换为完整年份。
///
/// 返回的年份将位于当前年份的 `lookBehindYears`(不包括在内)
/// 之前和 `100 - lookBehindYears`(包括在内)之后。
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);
}
英文:
You currently do:
> dart
> 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
}
答案2
得分: 0
使用如果大于则添加的方法,这样就可以修复大多数年份错误,检查不依赖于年份的*YY--
*部分,所以你不能确定只看这个字符串是不是正确的。
DateTime? mzt_parse_date(String date, String check) {
final cut_year = 69; // 和 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
,你可以在这一行做和之前一样的操作,但是反过来。
String formattedDate = '$centuryAdjustedYear-$month-$day';
或者使用Datetime
类型。
String date_to_ddmmyyyy(DateTime date) {
return '${date.day}-${date.month}-${date.year}';
}
英文:
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}';
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论