1. 程式人生 > 實用技巧 >記java.text.SimpleDateFormat轉換yyyyMMdd格式時顯示錯誤的問題

記java.text.SimpleDateFormat轉換yyyyMMdd格式時顯示錯誤的問題

場景:

專案中儲存使用者身份證有效期的欄位儲存格式為yyyyMMdd,而使用第三方OCR解析包也並不能保證100%的正確率,所有我們需要校驗下格式是否有誤。

如:使用者實際過期時間為20220530,但因照片有些模糊就解析成20200538了。

準備工作:

準備好工具類,有如下幾個函式:

 1 public static String dateToString(Date date, String formate) {
 2     if (date == null) {
 3         return "";
 4     }
 5     DateFormat dateFormat = new SimpleDateFormat(formate);
6 return dateFormat.format(date); 7 } 8 9 public static Date string2date(String dateString, String formatStr) { 10 Date formateDate = null; 11 DateFormat format = new SimpleDateFormat(formatStr); 12 try { 13 formateDate = format.parse(dateString); 14 } catch (ParseException e) {
15 return null; 16 } 17 return formateDate; 18 } 19 20 /** 21 * 將字元型別的日期轉換輸出形式 22 * 如:20190101 >>> 2019-01-01; value=20190101, form=yyyyMMdd, to=yyyy-MM-dd 23 * 24 * @param value 待轉換的值 25 * @param from 原字元日期輸出格式 26 * @param to 轉換後的日期輸出格式 27 * @return 28 */ 29 public static String string2string(String value, String from, String to) {
30 return dateToString(string2date(value, from), to); 31 } 32 33 /** 34 * 校驗yyyyMMdd格式的日期是否正確 35 * <p> 36 * 因new SimpleDateFormat(format).parse(dateStr)在轉換錯誤的yyyyMMdd格式時並不會丟擲ParseException,所以需要另作處理: 37 * 1、首先將yyyyMMdd轉換成yyyy-MM-dd格式(此時不會丟擲異常,但會顯示與之前不一樣的時間) 38 * 2、將第一步轉換後得出的時間與源時間進行比較,相同則為正確格式的日期,不同則為錯誤格式的日期 39 * <p> 40 * 如:source = "20200835" 41 * 1、format = "2019-12-08" 42 * 2、replace = "20191208" 43 * 3、source.equals(replace) = false 44 * 45 * @param source 日期源 46 * @return true-格式正確,false-格式錯誤 47 */ 48 public static boolean verify_yyyyMMdd(String source) { 49 String format = string2string(source, DateFormatUtil.YYYYMMDD, DateFormatUtil.YYYY_MM_DD); 50 String replace = format.replace("-", ""); 51 return source.equals(replace); 52 }

遇到的坑:

使用java.text.SimpleDateFormat轉換yyyyMMdd格式時會轉換成預期之外的時間,如20200835會轉換成20191208(上述程式碼的註釋)。

解決方案:

因為我不能改變第三方OCR的解析,所有我就需要在OCR解析到錯誤的值時讓使用者重新發起,所以我這裡做的也只是對日期的校驗。

方案如下(同樣的註釋也說得很清楚):

  • 首先將yyyyMMdd轉換成yyyy-MM-dd格式(此時不會丟擲異常,但會顯示與之前不一樣的時間)
  • 將第一步轉換後得出的時間與源時間進行比較,相同則為正確格式的日期,不同則為錯誤格式的日期
1 boolean identityStartVerify = DateFormatUtil.verify_yyyyMMdd(customer.getIdentityStart());
2 boolean identityExpiresVerify = DateFormatUtil.verify_yyyyMMdd(customer.getIdentityExpires());
3 if (!identityStartVerify || !identityExpiresVerify) {
4     logger.info("{} 身份證格式有誤,identityStartVerify={} identityExpiresVerify={}", orderId,
5             identityStartVerify, identityExpiresVerify);
6     return Response.fail("身份證格式有誤");
7 }