Java中部分合法日期用SimpleDateFormat解析抛出异常问题
问题原因解析
你遇到的这个问题是夏令时(DST)切换导致的。2010年10月17日在部分时区(比如巴西的BRT/BRST时区),当地时间不存在00:00:00这个时刻——因为夏令时切换时,时钟会从10月16日的23:59直接跳转到10月17日的01:00,跳过了整个00:00小时。
当你设置setLenient(false)后,SimpleDateFormat会严格校验时间的合法性,不存在的时刻自然会抛出解析异常;而前后日期没有夏令时切换,对应的时刻真实存在,所以能正常解析。
验证与解决方法
指定无夏令时时区
显式将时区设置为UTC(或其他无夏令时的时区),就能正常解析该日期:@Test public void testWithUtcTimeZone() throws ParseException { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setLenient(false); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date parsedDate = dateFormat.parse("2010-10-17 00:00:00"); assertNotNull(parsedDate); }使用Java 8新日期API
SimpleDateFormat不仅线程不安全,对夏令时的处理也不够直观。推荐使用Java 8引入的java.time包下的API,比如LocalDateTime(不涉及时区)或ZonedDateTime(处理时区):@Test public void testWithJavaTimeApi() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime dateTime = LocalDateTime.parse("2010-10-17 00:00:00", formatter); assertNotNull(dateTime); }如果需要处理时区,
ZonedDateTime会明确提示夏令时相关的时间问题,比旧API更健壮。
内容的提问来源于stack exchange,提问作者Ronei Vinicius Gebert
相关产品推荐
相关产品推荐

