转换为 java.sql.Date

Conversion to java.sql.Date

我有一个String需要转换成java.sql.Date格式:

2017-08-31 01:40:00+00:00

我正在使用下面的代码,我可以看到日期仅被解析为 2017-08-31 而不是上面的整个字符串。有人可以建议吗?

java.util.Date utilDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(dateTimeStamp);

java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

根据回答中的建议,我实现如下:

String dateTimeStamp = "2017-08-31 01:40:00+00:00";
java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ssZZ");
java.util.Date date = format.parse(dateTimeStamp);
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.getTime());
System.out.println("timestamp - " + timestamp);

但是,出现以下错误:

java.text.ParseException: Unparseable date: "2017-08-31 01:40:00+00:00"
        at java.text.DateFormat.parse(DateFormat.java:366)
        at com.eneco.mysqlsink.WeatherForecastSink.WeatherForecastTask.put(WeatherForecastTask.java:94)
        at org.apache.kafka.connect.runtime.WorkerSinkTask.deliverMessages(WorkerSinkTask.java:435)
        at org.apache.kafka.connect.runtime.WorkerSinkTask.poll(WorkerSinkTask.java:251)
        at org.apache.kafka.connect.runtime.WorkerSinkTask.iteration(WorkerSinkTask.java:180)
        at org.apache.kafka.connect.runtime.WorkerSinkTask.execute(WorkerSinkTask.java:148)
        at org.apache.kafka.connect.runtime.WorkerTask.doRun(WorkerTask.java:146)
        at org.apache.kafka.connect.runtime.WorkerTask.run(WorkerTask.java:190)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

您需要在格式中包含时区标识符

java.util.Date utilDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ssZZ").parse(dateTimeStamp);
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime()); 

要获得 timestamp,只需使用 java.sql.Timestamp 而不是 java.sql.Date

java.sql.Timestamp对象的toString()方法应该return你需要的字符串。

java.sql.Date 只提供日期。您需要使用 java.sql.Timestamp 来获取日期和时间。

java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
java.util.Date date = format.parse("2017-08-31 01:40:00+00:00");
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.getTime());
System.out.println(timestamp);

您使用的格式很好,但您丢失了时区偏移量。

如果您想考虑时区偏移,请使用以下格式。

java.util.Date utilDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(dateTimeStamp);

结果:

utilDate = Thu Aug 31 01:40:00 IST 2017

java.util.Date utilDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ssX").parse(dateTimeStamp);

结果:

utilDate = Thu Aug 31 07:10:00 IST 2017.

我是 运行 这个来自印度的代码,时区偏移 05:30 小时。

您正在使用 hh 模式,它对应于 hour-of-am-pm field(值从 1 到 12)。由于输入没有 AM/PM 指示符,这不会总是按预期工作。您必须将其更改为 HH 小时,值从 0 到 23)。

此外,要解析偏移量 +00:00,您需要使用 X 模式:

String input = "2017-08-31 01:40:00+00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssX");
// java.util.Date
Date date = sdf.parse(input);

X 模式是在 Java 7 中引入的。如果您使用的是旧版本,您还可以在格式化程序中设置 UTC 时区:

// "X" is not supported
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// set UTC in the formatter
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
// java.util.Date
Date date = sdf.parse(input);

这更糟,因为您需要知道输入的偏移量并将其设置在格式化程序中。所以如果支持,最好使用X

然后您可以从 java.util.Date:

创建 sql 日期
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
java.sql.Timestamp timestamp = new Timestamp(date.getTime());

但请注意,如果您只是 System.out.println sql 日期或时间戳,它们将被转换为 JVM 默认时区(给您错误的印象:请参阅 this article了解更多详情)。

此外,请记住 java.sql.Date 只是 keeps the date fields (day/month/year), setting the hours to zero (so the 01:40 is lost). A java.sql.Timestamp, on the other hand, preserves the whole UTC millis value


Java新Date/TimeAPI

旧的 classes(DateCalendarSimpleDateFormat)有 lots of problems and design issues,它们正在被新的 APIs.

如果您正在使用 Java 8,请考虑使用 new java.time API. It's easier, less bugged and less error-prone than the old APIs.

如果您使用 Java 6 或 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it ).

下面的代码适用于两者。 唯一的区别是包名称(在 Java 8 中是 java.time,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp),但是 classes和方法名称是一样的。

首先您将输入解析为 OffsetDateTime,使用 DateTimeFormatter 指定格式:

String input = "2017-08-31 01:40:00+00:00";

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssXXX");
OffsetDateTime odt = OffsetDateTime.parse(input, fmt);

然后你可以把它转换成sql类型。在Java8中,有内置的方法可以做到:

java.sql.Date sqlDate = java.sql.Date.valueOf(odt.toLocalDate());
java.sql.Timestamp sqlTimestamp = java.sql.Timestamp.from(odt.toInstant());

在 Java 7 中,ThreeTen Backport 具有 org.threeten.bp.DateTimeUtils class:

java.sql.Date sqlDate = DateTimeUtils.toSqlDate(odt.toLocalDate());
java.sql.Timestamp sqlTimestamp = DateTimeUtils.toSqlTimestamp(odt.toInstant());