String str = "2017-08-01T15:15:03.313456768+02:00";
// The following statement gives IllegalArgumentExceptionTimestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
Timestamp timeStamp = Timestamp.valueOf(str);
ZonedDateTime zoneddate = ZonedDateTime.parse(str);
System.out.println("ZonedDate: "+zoneddate);// prints 2017-08-01T15:15:03.313456768+02:00
Instant inst = zoneddate.toInstant();
Timestamp newTime = Timestamp.from(inst);
System.out.println("Timestamp: "+newTime);// prints 2017-08-01 15:15:03.313456768 without Zone
我在转换期间错过了区域。任何人都可以建议我如何在TimeStamp
中获得Zone?
答案 0 :(得分:2)
这个问题的最新版本是:
有人可以建议我如何在TimeStamp中获得Zone
简单的答案是你不能。 Timestamp
并不包含区域作为其表示的一部分。当您转换从Timestamp
生成ZonedDateTime
时,您扔掉时区偏移量。
您可以通过查看Timestamp
类的源代码来验证这一点。没有允许您传递时区信息的构造函数,日期/时间表示为UTC。 (getTimezoneOffset()
方法返回不同的内容......无论如何都不推荐使用该方法。)
...但我必须在数据库中保留Timestamp,它必须显示区域。
然后,您需要使用不同的SQL类型(或多种类型)来表示时间戳,以及Java端的相应类型。请注意,SQL的某些方言不会在标准DATE / TIME / TIMESTAMP类型中存储时区信息。
答案 1 :(得分:1)
Stephen C的回答是正确的。
避免使用麻烦的旧日期时间类,例如java.sql.Timestamp
。现在取代了java.time类。
您有一个标准ISO 8601格式的字符串,表示日期时间与UTC的偏移量,但没有时区的指示。因此解析为OffsetDateTime
。以Instant
的形式移至UTC进行存储。
检索后,指定您想要的任何时区。
String input = "2017-08-01T15:15:03.313456768+02:00";
OffsetDateTime odt = OffsetDateTime.parse( input ) ;
Instant instant = odt.toInstant() ; // Adjust into UTC for storage.
myPreparedStatement.setObject( … , instant ) ;
提取。
Instant instant = myResultSet.getObject( … , Instant.class ) ;
ZoneId z = ZoneId.of( "America/Montreal" ) ; // or "Europe/Berlin", "Asia/Kolkata", whatever.
ZonedDateTime zdt = instant.atZone( z ) ; // Move from UTC to a time zone.
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。