转换为java.sql.Date

时间:2017-09-18 09:41:36

标签: java simpledateformat date-parsing java-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)

5 个答案:

答案 0 :(得分:2)

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);

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

您正在使用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);

在Java 7中引入了X模式。如果您使用的是旧版本,还可以在格式化程序中设置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(日/月/年),将小时数设置为零(因此01:40会丢失)。另一方面,java.sql.Timestamp会保留whole UTC millis value

Java新日期/时间API

旧类(DateCalendarSimpleDateFormat)有lots of problemsdesign issues,它们将被新API取代。< / p>

如果您使用的是 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs

如果您使用的是 Java 6或7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,您还需要ThreeTenABP(更多关于如何使用它here)。

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

首先,您使用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类型。在Java 8中,有内置的方法可以做到这一点:

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类:

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

答案 3 :(得分:0)

要让timestamp只使用java.sql.Timestamp而不是java.sql.Date

toString()对象的java.sql.Timestamp方法应该根据需要返回字符串。

答案 4 :(得分:0)

您正在使用的格式很好,但是您的时区偏移已经松动。

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

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小时的偏差。