使用DateTimeFormatter按yyyy-MM-dd HH:mm:ss格式解析字符串至LocalDateTime时秒数丢失的问题
DateTimeFormatter按yyyy-MM-dd HH:mm:ss格式解析字符串至LocalDateTime时秒数丢失的问题
嘿,我来帮你拆解这个问题里的几个关键点,其实都是Java 8日期API的设计细节在搞怪~
1. 秒数并没有真的丢失!只是默认输出省略了
你看到的2010-12-31T00:00只是LocalDateTime默认toString()方法的输出规则——当秒数为0时,它会自动省略这部分,但实际上解析后的对象里是包含秒数的。
你可以加一行代码验证一下:
System.out.println("Parsed second value: " + parsed.getSecond());
不管你用yyyy-MM-dd HH:mm:ss还是yyyy-MM-dd HH:mm解析对应的字符串,只要原字符串里有秒(比如00:00:00),getSecond()都会返回0,说明秒数是存在的,只是打印的时候没显示而已。
而SimpleDateFormat的输出会强制显示所有格式部分,这就是它和Java 8日期API默认输出的区别,不是解析出了问题。
2. 带T的字符串解析失败的原因
你尝试解析2010-12-31T00:00:00时用了yyyy-MM-dd HH:mm:ss模式,这里的问题是:模式里的空格 和字符串里的T不匹配!
要正确解析这种带T的ISO风格字符串,需要把模式里的空格换成转义后的'T',也就是:
pattern = "yyyy-MM-dd'T'HH:mm:ss"; parsed = LocalDateTime.parse(toParse, DateTimeFormatter.ofPattern(pattern));
这样就能成功解析带T的日期时间字符串了。
3. 关于LocalDateTime转Instant失败的问题
你提到的DateTimeException是因为LocalDateTime是不带时区信息的日期时间对象,而Instant是UTC时间线上的瞬时点,两者之间无法直接转换。
解决办法是给LocalDateTime指定一个时区,转成ZonedDateTime或者OffsetDateTime后再转Instant,比如:
// 用系统默认时区 Instant instant = parsed.atZone(ZoneId.systemDefault()).toInstant(); // 或者指定UTC时区 Instant instantUtc = parsed.atZone(ZoneOffset.UTC).toInstant();
修改后的可运行示例
给你调整后的代码,能更清楚看到这些点:
package main; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.Instant; import java.time.format.DateTimeFormatter; public class Test_yyyy_MM_dd_HH_mm_ss { public static void main(String[] args) { String toParse, pattern; LocalDateTime parsed; // 测试带秒的字符串解析,验证秒数存在 toParse = "2010-12-31 00:00:00"; pattern = "yyyy-MM-dd HH:mm:ss"; parsed = LocalDateTime.parse(toParse, DateTimeFormatter.ofPattern(pattern)); System.out.println("Parsing \"" + toParse + "\" with pattern \"" + pattern + "\" returns " + parsed); System.out.println("Actual second value: " + parsed.getSecond()); // 输出0,说明秒存在 // 测试不带秒的字符串解析 toParse = "2010-12-31 00:00"; pattern = "yyyy-MM-dd HH:mm"; parsed = LocalDateTime.parse(toParse, DateTimeFormatter.ofPattern(pattern)); System.out.println("Parsing \"" + toParse + "\" with pattern \"" + pattern + "\" returns " + parsed); System.out.println("Actual second value: " + parsed.getSecond()); // 同样输出0,因为LocalDateTime默认秒为0 // 测试带T的字符串解析 toParse = "2010-12-31T00:00:00"; pattern = "yyyy-MM-dd'T'HH:mm:ss"; parsed = LocalDateTime.parse(toParse, DateTimeFormatter.ofPattern(pattern)); System.out.println("Parsing \"" + toParse + "\" with pattern \"" + pattern + "\" returns " + parsed); // 测试转Instant Instant instant = parsed.atZone(ZoneId.systemDefault()).toInstant(); System.out.println("Converted to Instant: " + instant); } }
内容来源于stack exchange
相关产品推荐
相关产品推荐

