您输入的日期时间字符串错误。
AM/PM 标记不适用于 24 小时格式的时间。它应该是2012-03-17 04:00:00 PM 或2012-03-17 16:00:00。
java.time
java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*。
另外,下面引用的是来自home page of Joda-Time的通知:
请注意,从 Java SE 8 开始,用户被要求迁移到 java.time (JSR-310) - JDK 的核心部分,它取代了这个项目。
使用现代日期时间 API java.time 的解决方案:
让我们首先尝试按照您的方式进行操作:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String startDateTime = "2012-03-17 16:00:00 PM";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd hh:mm:ss a", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(startDateTime, dtf);
System.out.println(ldt);
}
}
输出:
线程“主”java.time.format.DateTimeParseException 中的异常:
无法解析文本“2012-03-17 16:00:00 PM”:值无效
ClockHourOfAmPm(有效值 1 - 12):16
如您所见,java.time API 正确地引发了异常,通知您该问题。另一方面,SimpleDateFormat 错误地解析了输入字符串。
现在,让我们看看如何正确解析它。为了正确解析它,我们将使用:
- 格式
uuuu-MM-dd HH:mm:ss 其中H 指定 24 小时格式。对于您的日期时间字符串,您可以使用 y 而不是 u 但 I prefer u to y。
- 函数
DateTimeFormatter#parse(CharSequence, ParsePosition) 将ParsePosition 索引设置为0。
演示:
import java.text.ParsePosition;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String startDateTime = "2012-03-17 16:00:00 PM";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
ParsePosition pp = new ParsePosition(0);
LocalDateTime ldt = LocalDateTime.from(dtf.parse(startDateTime, pp));
System.out.println(ldt);
}
}
输出:
2012-03-17T16:00
ONLINE DEMO
注意:Never use SimpleDateFormat or DateTimeFormatter without a Locale.
从 Trail: Date Time 了解有关现代日期时间 API 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。