Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中将时间戳转换为instant会增加不必要的时间偏移_Java_Mysql_Datetime_Utc_Timezone Offset - Fatal编程技术网

Java中将时间戳转换为instant会增加不必要的时间偏移

Java中将时间戳转换为instant会增加不必要的时间偏移,java,mysql,datetime,utc,timezone-offset,Java,Mysql,Datetime,Utc,Timezone Offset,我需要能够将从存储在“datetime”字段中的MySQL数据库获取的数据转换为JavaZonedDateTime对象 ZonedDateTime dt = ZonedDateTime.ofInstant(rs.getTimestamp("Start").toInstant(), UTC_ZONE_ID) 我遇到的问题是toInstant()将本地时间偏移添加到Timestamp对象,我不需要它,因为datetime已经以UTC格式存储在数据库中。 因此,当我运行以下代码时: ZonedDat

我需要能够将从存储在“datetime”字段中的MySQL数据库获取的数据转换为Java
ZonedDateTime
对象

ZonedDateTime dt = ZonedDateTime.ofInstant(rs.getTimestamp("Start").toInstant(), UTC_ZONE_ID)
我遇到的问题是
toInstant()
将本地时间偏移添加到
Timestamp
对象,我不需要它,因为datetime已经以UTC格式存储在数据库中。 因此,当我运行以下代码时:

ZonedDateTime startDT = 
        ZonedDateTime.ofInstant(rs.getTimestamp("Start").toInstant(),Globals.LOCALZONEID);
System.out.println(rs.getTimestamp("start"));
System.out.println(rs.getTimestamp("start").toInstant());
我得到:

2017-06-08 13:15:00.0
2017-06-08T17:15:00Z
我需要时间部分保持不变

我找不到任何明显的问题解决方案,所以我在这里遗漏了什么吗?

时间戳
&
即时
始终使用UTC 我遇到的问题是向Timestamp对象添加本地时间偏移

不,没有

  • 从定义上讲,A是一个概念
  • A定义为UTC
两者都不能指定任何其他分区

不要把代码集中到一行中。将每个步骤分成单独的行,以便调试它们的值

java.sql.Timestamp ts = rs.getTimestamp("Start") ;  // Actually in UTC, but it's `toString` method applies JVM’s current default time zone while generating string.
Instant instant = ts.toInstant() ;                  // Same moment, also in UTC.
ZoneId z = ZoneId.of( "America/Montreal" ) ;        // Or call your global var: `Globals.LOCALZONEID`.
ZonedDateTime zdt = instant.atZone( z );            // Same moment, same point on timeline, but with wall-clock time seen in a particular zone.
之后,您可能会看到问题(或非问题)。如果没有,请编辑问题以显示每个变量的调试值

不要信任时间戳::toString 重要提示:方法位于
java.sql.Timestamp::toString
。该方法在生成字符串时应用JVM的当前默认时区。实际值始终以UTC为单位。避免这些麻烦的遗留类的众多原因之一。在您自己的计算机上运行以下代码示例,以查看默认时区对
时间戳的文本表示的影响

让我们模拟一下。IdeOne.com上的JVM默认为UTC/GMT,因此我们通过任意指定默认值为
Pacific/Auckland
来覆盖默认值

Instant now = Instant.now() ;                       // Simulating fetching a `Timestamp` from database by using current moment in UTC.

TimeZone.setDefault( TimeZone.getTimeZone( "Pacific/Auckland" ) ) ;
ZoneId zoneIdDefault = ZoneId.systemDefault() ;
ZoneOffset zoneOffset = zoneIdDefault.getRules().getOffset( now ) ;

java.sql.Timestamp ts = java.sql.Timestamp.from( now ) ;  // Actually in UTC, but it's `toString` method applies JVM’s current default time zone while generating string.
Instant instant = ts.toInstant() ;                  // Same moment, also in UTC.
ZoneId z = ZoneId.of( "America/Montreal" ) ;        // Or call your global var: `Globals.LOCALZONEID`.
ZonedDateTime zdt = instant.atZone( z );            // Same moment, same point on timeline, but with wall-clock time seen in a particular zone.
当前默认时区:太平洋/奥克兰

UTC当前默认偏移量:太平洋/奥克兰|总秒数:43200

现在.toString():2017-06-09T04:41:10.750Z

T.toString():2017-06-09 16:41:10.75

instant.toString():2017-06-09T04:41:10.750Z

z、 toString():美国/蒙特利尔

zdt.toString():2017-06-09T00:41:10.750-04:00[美国/蒙特利尔]

避免遗留日期时间类 在java.time包之外发现的旧日期时间类麻烦、混乱、设计糟糕,而且有缺陷。尽可能避免它们。这包括
java.sql.Timestamp

您的compliant可以通过调用和直接处理java.time类型

……还有

Instant instant = myResultSet.getObject( … , Instant.class ) ;
Instant instant = myResultSet.getTimestamp( … ).toInstant() ;
如果使用尚未更新到JDBC 4.2和java.time的JDBC驱动程序,请使用添加到旧类中的新方法将其短暂转换为
java.sql.Timestamp
,诸如此类。但除了与数据库交换数据之外,您还可以使用java.time对象完成所有实际工作(业务逻辑)

myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;
……还有

Instant instant = myResultSet.getObject( … , Instant.class ) ;
Instant instant = myResultSet.getTimestamp( … ).toInstant() ;

关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*

从哪里获得java.time类

  • ,及以后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类
    • 对于早期Android(
      Timestamp
      &
      Instant
      始终以UTC为单位 我遇到的问题是向Timestamp对象添加本地时间偏移

      不,没有

      • 从定义上讲,A是一个概念
      • A定义为UTC
      两者都不能指定任何其他分区

      不要把你的代码放在一行中。把每一步分成几行,这样你就可以调试它们的值了

      java.sql.Timestamp ts = rs.getTimestamp("Start") ;  // Actually in UTC, but it's `toString` method applies JVM’s current default time zone while generating string.
      Instant instant = ts.toInstant() ;                  // Same moment, also in UTC.
      ZoneId z = ZoneId.of( "America/Montreal" ) ;        // Or call your global var: `Globals.LOCALZONEID`.
      ZonedDateTime zdt = instant.atZone( z );            // Same moment, same point on timeline, but with wall-clock time seen in a particular zone.
      
      之后,您可能会看到问题(或非问题)。如果没有,请编辑问题以显示每个变量的调试值

      不要信任时间戳::toString
重要提示:java.sql.Timestamp::toString方法位于。该方法在生成字符串时应用JVM的当前默认时区。实际值始终以UTC为单位。避免这些麻烦的遗留类的原因之一。在您自己的计算机上运行以下代码示例以查看对f
时间戳
文本表示上的默认时区

让我们对此进行模拟。IdeOne.com上的JVM默认为UTC/GMT,因此我们通过任意指定默认值为
Pacific/Auckland
来覆盖默认值

Instant now = Instant.now() ;                       // Simulating fetching a `Timestamp` from database by using current moment in UTC.

TimeZone.setDefault( TimeZone.getTimeZone( "Pacific/Auckland" ) ) ;
ZoneId zoneIdDefault = ZoneId.systemDefault() ;
ZoneOffset zoneOffset = zoneIdDefault.getRules().getOffset( now ) ;

java.sql.Timestamp ts = java.sql.Timestamp.from( now ) ;  // Actually in UTC, but it's `toString` method applies JVM’s current default time zone while generating string.
Instant instant = ts.toInstant() ;                  // Same moment, also in UTC.
ZoneId z = ZoneId.of( "America/Montreal" ) ;        // Or call your global var: `Globals.LOCALZONEID`.
ZonedDateTime zdt = instant.atZone( z );            // Same moment, same point on timeline, but with wall-clock time seen in a particular zone.
当前默认时区:太平洋/奥克兰

UTC当前默认偏移量:太平洋/奥克兰|总秒数:43200

现在.toString():2017-06-09T04:41:10.750Z

T.toString():2017-06-09 16:41:10.75

instant.toString():2017-06-09T04:41:10.750Z

z、 toString():美国/蒙特利尔

zdt.toString():2017-06-09T00:41:10.750-04:00[美国/蒙特利尔]

避免遗留日期时间类 在java.time包之外发现的旧日期-时间类麻烦、混乱、设计糟糕且有缺陷。请尽可能避免它们。这包括
java.sql.Timestamp

您的compliant可以通过调用和直接处理java.time类型

……还有

Instant instant = myResultSet.getObject( … , Instant.class ) ;
Instant instant = myResultSet.getTimestamp( … ).toInstant() ;
如果使用尚未更新到JDBC 4.2和java.time的JDBC驱动程序,请使用添加到ol的新方法将其短暂转换为
java.sql.Timestamp