Flutter护照MRZ两位年份日期格式转换问题求助
解决方案:Flutter中MRZ日期转换问题
问题根源分析
- intl插件报错原因:你直接用了错误的DateFormat格式(比如
yyyyMMdd)解析6位MRZ日期(YYMMDD格式),yyyy要求4位年份,解析6位字符串时会因长度不匹配抛出Trying to read MM from 000423 at position 6错误。 - 自定义Dart代码失效原因:未区分出生日期与护照有效期的年份处理逻辑——出生日期是过去日期,有效期是未来日期,两者的世纪补全规则不同。
方案1:自定义Dart转换函数(推荐)
通过明确区分日期类型(生日/有效期),补全正确的世纪,避免转换错误:
String convertMRZDate(String mrzDate, {bool isBirthDate = true}) { // 校验MRZ日期格式 if (mrzDate.length != 6) { throw ArgumentError('MRZ日期必须是6位字符串'); } // 拆分MRZ日期:YY MM DD final yearStr = mrzDate.substring(0, 2); final monthStr = mrzDate.substring(2, 4); final dayStr = mrzDate.substring(4, 6); final int twoDigitYear = int.parse(yearStr); final currentYear = DateTime.now().year; final currentTwoDigitYear = currentYear % 100; int fullYear; if (isBirthDate) { // 出生日期:两位年份大于当前年份后两位,补19xx;否则补20xx fullYear = twoDigitYear > currentTwoDigitYear ? 1900 + twoDigitYear : 2000 + twoDigitYear; } else { // 有效期:两位年份小于等于当前年份后两位,补21xx;否则补20xx(适配未来有效期) fullYear = twoDigitYear <= currentTwoDigitYear ? 2100 + twoDigitYear : 2000 + twoDigitYear; } // 构造日期并格式化输出 final date = DateTime(fullYear, int.parse(monthStr), int.parse(dayStr)); return '${dayStr}-${monthStr}-${fullYear.toString().padLeft(4, '0')}'; }
使用示例
// 转换出生日期:000423 → 23-04-2000 print(convertMRZDate('000423', isBirthDate: true)); // 转换有效期:301231 → 31-12-2030 print(convertMRZDate('301231', isBirthDate: false));
方案2:intl插件正确用法
先按YYMMDD格式解析,再根据日期类型调整世纪:
import 'package:intl/intl.dart'; String convertMRZDateWithIntl(String mrzDate, {bool isBirthDate = true}) { if (mrzDate.length != 6) { throw ArgumentError('MRZ日期必须是6位字符串'); } // 按YYMMDD格式解析MRZ日期 final mrzFormat = DateFormat('yyMMdd'); DateTime date = mrzFormat.parse(mrzDate); final currentYear = DateTime.now().year; // 调整世纪:生日取过去的世纪,有效期取未来的世纪 if (isBirthDate && date.year > currentYear) { date = date.subtract(const Duration(days: 36524)); // 减去约100年 } else if (!isBirthDate && date.year < currentYear) { date = date.add(const Duration(days: 36524)); // 加上约100年 } // 格式化为dd-MM-yyyy final outputFormat = DateFormat('dd-MM-yyyy'); return outputFormat.format(date); }
内容的提问来源于stack exchange,提问作者abhi
相关产品推荐
相关产品推荐

