为Timestamp.valueOf获取不同的值

时间:2019-01-10 07:09:13

标签: java scala

我正在尝试通过获取2018-09-04 13:43:32.922000的时间戳值 Timestamp.valueOf("2018-09-04 13:43:32.922000")

我的预期输出是2018-09-04 13:43:32.922

但是我得到了2018-09-04 01:13:32.922

这可能是由于时区不同所致,因为我在印度的团队获得了准确的结果,但是我在加利福尼亚的这里获得了不同的结果。 提出可以解决此问题的更改。

2 个答案:

答案 0 :(得分:6)

tl; dr

myPreparedStatement.setObject( 
    Instant
    .parse( 
        "2018-09-04 13:43:32.922000"
        .replace( " " , "T" )
        .concat( "Z" )  
    ) 
    .atZone(
        ZoneOffset.UTC
    )
)

java.time

  

建议可以解决此问题的更改。

请勿使用java.sql.Timestamp

该类的许多缺陷中的一个是method you call is not documented在解析时解释其行为。您的JVM的当前默认时区似乎正在通过一些调整以静默方式应用。但问题是有争议的。

几年前,现代的 java.time 类通过采用JSR 310(特别是InstantOffsetDateTime)来取代了这个经过精心设计的类。

通过将中间的SPACE替换为T,将输入字符串更改为标准ISO 8601格式。

String input = "2018-09-04 13:43:32.922000".replace( " " , "T" ) ;

您的输入是否打算代表UTC中的时刻,偏移量为零?如果是这样,请附加一个Z(发音为Zulu)。

String input = "2018-09-04 13:43:32.922000".replace( " " , "T" ).concat( "Z" ) ;

Instant类表示UTC中的时刻,根据定义始终为UTC。

Instant instant = Instant.parse( input ) ;

您的JDBC driver可以选择接受Instant对象。

myPreparedStatement.setObject( instant ) ;

如果您的JDBC驱动程序不支持Instant,请使用OffsetDateTime。 JDBC 4.2和更高版本中需要支持。

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ; 
myPreparedStatement.setObject( odt ) ;

请注意,您的JVM在运行时的当前默认时区与当前的时区无关,对上面的代码没有影响。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance 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中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:-3)

我不认为问题出在不同的时区。只是您得到的输出为24小时格式,并且需要将其转换为12小时格式。请参考How to convert 24 hr format time in to 12 hr Format?将时间转换为12小时格式。