Java 8解析带PM标记的单数字小时失败问题求助
解决日期解析的兼容与严格校验问题
这个场景太常见了——既要兼容单双位数的小时格式,又不想放松对非法时间的校验,完全理解你的痛点!下面给你一个精准的解决方案:
核心思路
问题出在两个关键点:
- 原来的日期格式模式可能强制要求小时是两位数(比如用了
hh或HH),导致单数字小时匹配失败; - 开启
lenient=true虽然能兼容格式,但会跳过时间合法性校验,出现33:50这种非法时间也能通过的情况。
正确的做法是:使用支持单双位数小时的格式模式,同时开启严格的解析规则。
代码实现(以Java为例)
假设你用的是Java的DateTimeFormatter(目前推荐的日期处理API),代码如下:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.ResolverStyle; import java.util.Locale; public class StrictDateParser { public static void main(String[] args) { // 定义格式模式: // MMM = 英文月份缩写(如Feb) // d = 单/双位数日期(如6或16) // yyyy = 四位年份 // h = 12小时制的单/双位数小时(如3或13) // mm = 两位分钟 // a = AM/PM标识 DateTimeFormatter strictFormatter = DateTimeFormatter.ofPattern("MMM d, yyyy h:mm a", Locale.US) .withResolverStyle(ResolverStyle.STRICT); // 开启严格校验模式 // 测试合法的单小时格式 try { LocalDateTime singleHourDt = LocalDateTime.parse("Feb 6, 2017 3:50 PM", strictFormatter); System.out.println("单小时格式解析成功:" + singleHourDt); } catch (Exception e) { System.out.println("单小时格式解析失败:" + e.getMessage()); } // 测试合法的双小时格式 try { LocalDateTime doubleHourDt = LocalDateTime.parse("Feb 6, 2017 13:50 PM", strictFormatter); System.out.println("双小时格式解析成功:" + doubleHourDt); } catch (Exception e) { System.out.println("双小时格式解析失败:" + e.getMessage()); } // 测试非法时间(33:50),预期解析失败 try { LocalDateTime invalidDt = LocalDateTime.parse("Feb 6, 2017 33:50 PM", strictFormatter); System.out.println("非法时间解析成功(不应该发生):" + invalidDt); } catch (Exception e) { System.out.println("非法时间解析失败(符合预期):" + e.getMessage()); } } }
关键细节解释
- 格式模式中的小时符号:
- 用
h表示12小时制的单/双位数小时(替代强制两位数的hh); - 如果是24小时制场景,用
H替代强制两位数的HH。
- 用
- 严格校验模式:
ResolverStyle.STRICT会严格校验时间的合法性,比如小时必须在1-12(12小时制)或0-23(24小时制)范围内,分钟必须在0-59之间,完全杜绝非法时间通过解析;
- Locale设置:
- 因为你的日期字符串是英文月份缩写,所以必须指定
Locale.US(或其他英文Locale),避免系统默认的非英文Locale导致月份解析失败。
- 因为你的日期字符串是英文月份缩写,所以必须指定
这样调整后,既能兼容单双位数的小时格式,又能保证只接受合法的时间值,完美解决你的问题!
内容的提问来源于stack exchange,提问作者user1008513
相关产品推荐
相关产品推荐

