Java 如何将字符串(2017-08-01T15:15:03.313000000+;02:00)转换为时间戳
我在转换过程中缺少区域。有人能告诉我如何在Java 如何将字符串(2017-08-01T15:15:03.313000000+;02:00)转换为时间戳,java,timestamp,datetime-parsing,Java,Timestamp,Datetime Parsing,我在转换过程中缺少区域。有人能告诉我如何在时间戳中获得区域吗?这个问题的最新版本是: 有人能建议我如何在时间戳中获得区域吗 简单的答案是你不能。时间戳不包括区域作为其表示的一部分。当您从ZonedDateTime转换生成时间戳时,您正在丢弃时区偏移量 您可以通过查看Timestamp类的源代码来验证这一点。没有允许您传入时区信息的构造函数,日期/时间表示为UTC。(getTimezoneOffset()的getTimezoneOffset()方法返回了一些不同的结果……但该方法还是不推荐使用。)
时间戳中获得区域吗?这个问题的最新版本是:
有人能建议我如何在时间戳中获得区域吗
简单的答案是你不能。时间戳
不包括区域作为其表示的一部分。当您从ZonedDateTime
转换生成时间戳时,您正在丢弃时区偏移量
您可以通过查看Timestamp
类的源代码来验证这一点。没有允许您传入时区信息的构造函数,日期/时间表示为UTC。(getTimezoneOffset()的getTimezoneOffset()方法返回了一些不同的结果……但该方法还是不推荐使用。)
。。。但我必须在数据库中保留时间戳,它必须显示区域
然后需要使用不同的SQL类型(或多个类型)来表示时间戳,以及Java端的相应类型。请注意,SQL的某些方言不以标准日期/时间/时间戳类型存储时区信息 斯蒂芬C的答案是正确的
避免麻烦的旧日期时间类,如java.sql.Timestamp
。现在被java.time类取代
您有一个标准ISO 8601格式的字符串,表示一个日期时间,该日期时间与UTC之间有偏移,但不表示时区。因此,将其解析为OffsetDateTime
。以即时
的方式进入UTC进行存储
检索时,指定您想要的任何时区
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
找回
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 ) ;
关于java.time
该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&
该项目现已启动,建议迁移到类
要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是
您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要java.sql.*
类
从哪里获得java.time类
- 然后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及
- 大部分java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(i红色alredy,但SimpleDataFormat不接受9位毫秒。
SimpleDataFormat
具有毫秒精度(小数点后仅3位)。对于超过3位的数字,您必须使用Java 8 newJava.time
API:区域没有丢失。时间戳只保留自1970-01-01T00:00Z
以来的纳秒数,它没有时区。打印时,toString()
方法被隐式调用,此方法将值调整为JVM默认时区(检查时区.getDefault()的值
,您可能处于当前偏移量为+02:00
)的区域。您所做的转换是正确的,您可以使用zoneddate.toInstant().equals(newTime.toInstant())进行检查。
(它将是true
)。也可以认为每个数据库的副本在时间戳/日期类型上的工作方式不同,您必须在相应的文档中检查如何执行此操作,如何保存时区信息,如何不丢失精度,等等。而且您还弄错了值(自1970-01-01T00:00Z以来的纳秒数
)具有表示形式(显示某些特定区域中的日/月/年/小时/分钟/等值)。存储的值通常相同(纳秒数)。向用户显示此值时,您可以选择一种格式(此值的表示形式)。此格式可以有区域,也可以没有区域。我建议-它谈论的是java.util.Date
,但时间戳
类似(实际上它扩展了日期
),因此所有概念都适用于这两种格式。
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.