java.time
java.util
日期时间 API 及其格式化 API已SimpleDateFormat
过时且容易出错。由于java.sql.Timestamp
extends java.util.Date
,它遇到了同样的问题。建议完全停止使用它们并切换到现代 Date-Time API *。
使用java.time
现代日期时间 API 的解决方案:DateTimeFormatter
您可以使用ResolverStyle
as定义一个ResolverStyle.STRICT
,ResolverStyle.SMART
默认情况下。
演示:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.time.format.SignStyle;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf =
new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 1, 4, SignStyle.NORMAL)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NORMAL)
.appendLiteral(' ')
.appendValue(ChronoField.HOUR_OF_DAY, 1, 2, SignStyle.NORMAL)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR, 1, 2, SignStyle.NORMAL)
.appendLiteral(':')
.appendValue(ChronoField.SECOND_OF_MINUTE, 1, 2, SignStyle.NORMAL)
.optionalStart()
.appendLiteral('.')
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 3, false)
.optionalEnd()
.toFormatter(Locale.ENGLISH)
.withResolverStyle(ResolverStyle.STRICT);
// Test
Stream.of(
"2008-06-31 23:59:59.000",
"2008-06-30 23:59:59.000",
"2008-6-30 23:59:59.000",
"2008-6-8 23:59:59.000",
"2008-6-8 2:59:59.000",
"2008-6-8 23:5:59.000",
"2008-6-8 23:59:9.000",
"2008-06-30 23:59:59"
).forEach (s -> {
try {
LocalDateTime ldt = LocalDateTime.parse(s, dtf);
System.out.println(ldt);
}catch(DateTimeParseException e) {
System.out.printf("%s is an invalid date-time string.%n", s);
// ...
}
});
}
}
输出:
2008-06-31 23:59:59.000 is an invalid date-time string.
2008-06-30T23:59:59
2008-06-30T23:59:59
2008-06-08T23:59:59
2008-06-08T02:59:59
2008-06-08T23:05:59
2008-06-08T23:59:09
2008-06-30T23:59:59
ONLINE DEMO
从Trail: Date Time了解有关现代日期时间 API 的更多信息。检查此答案和此答案以了解如何将java.time
API 与 JDBC 一起使用。
如果有的话,您需要一个实例java.sql.Timestamp
:
您可以将 a 转换LocalDateTime
为java.sql.Timestamp
使用Timestamp#valueOf
例如
LocalDateTime now = LocalDateTime.now();
Timestamp ts = Timestamp.valueOf(now);
* 如果您正在为一个 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请通过 desugaring 检查可用的 Java 8+ API。请注意,Android 8.0 Oreo 已经提供对java.time
.