我正在尝试解析以下日期时间字符串
2018-01-30T23:59:59.000
我无法理解它是哪种标准格式,例如UTC或ISO_8601
同时以以下方式进行解析:
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD'T'HH:MM:SS:MS");
Date date = null;
try {
date = sdf.parse("2018-01-30T23:59:59.000");
} catch (ParseException e) {
e.printStackTrace();
}
但是它抛出以下异常:
java.text.ParseException: Unparseable date: "2018-01-30T23:59:59.000"
任何帮助表示赞赏。
最佳答案
LocalDateTime dateTime = LocalDateTime.parse("2018-01-30T23:59:59.000");
System.out.println(dateTime);
打印:
2018-01-30T23:59:59
您的字符串采用ISO 8601格式。 UTC或协调世界时不是一种格式,它是一种标准时间,用于定义我们各自时区中其余时间的使用时间。
您使用的日期时间类
SimpleDateFormat
和Date
早已过时,尤其是前者特别麻烦。我建议您改为使用现代Java日期和时间API java.time
。与之合作真是太好了。LocalDateTime
是具有一天中的时间,没有时区或与UTC偏移的日期。它的一元参数parse
方法解析ISO 8601,这就是为什么不需要显式格式化程序的原因。您的代码出了什么问题
您的格式模式字符串有很多问题。这是为什么您应该在没有任何显式格式化程序的情况下欣赏上述解决方案的原因之一。出错的第一件事是:格式模式字符串的冒号
:
在秒和毫秒之间,而日期时间字符串的点是.
。这就是为什么您会得到例外。但是,解决此问题,您的代码将产生以下
Date
:周日2017年12月31日23:00:00
与预期的日期有一个月的距离,而分钟和秒钟也丢失了。因为:
大写字母
YYYY
用于基于周的年份,仅与星期数一起使用。您需要小写的yyyy
年份。大写字母
DD
是一年中的某天。您需要在每月的某天使用小写字母dd
。您正确使用了大写字母
MM
表示月份。再尝试几分钟,将无法正常工作。也许您现在可以猜测:它是小写的mm
。毫不奇怪,您需要小写
ss
几秒钟。使用
MS
毫秒很有趣。 SimpleDateFormat
将其作为月份的M
(我们已经有过两次),将大写的S
用作毫秒。相反,您需要大写的SSS
为三位数字的毫秒。链接
Oracle tutorial: Date Time解释如何使用
java.time
。Wikipedia article: ISO 8601
在UTC上Wikipedia article: Coordinated Universal Time