从java.util.Date到java.sql.Timestamp时添加了无法解释的零 [英] Unexplained zero added when going from java.util.Date to java.sql.Timestamp

查看:144
本文介绍了从java.util.Date到java.sql.Timestamp时添加了无法解释的零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下测试代码(在ideone.com上尝试一下-在线Java编译器):

Consider the following test code (Try it here yourself on ideone.com - an online Java compiler):

class Main {
    public static void main (String[] args) throws Exception {
        Main m = new Main();
        m.test1();
        System.out.println();
        m.test2();
    }

    void test1() throws Exception {
        System.out.println("TEST 1: ");

        String strTimestamp = "1957-04-27 00:00:00.01";
        System.out.println(strTimestamp + " [Original String]");

        String format = "yyyy-MM-dd HH:mm:ss.SS";
        System.out.println(format + " [Format used]");
        java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(format);

        // Convert String to Date:
        java.util.Date date = formatter.parse(strTimestamp);
        long time = date.getTime();
        System.out.println(formatter.format(time) + " [Date#getTime() with same format]");

        java.sql.Timestamp timestamp = new java.sql.Timestamp(time);
        System.out.println(timestamp + " [Timestamp]");
    }

    void test2() throws Exception {
        System.out.println("TEST 2: ");

        String strTimestamp = "1957-04-27 00:00:00.001";
        System.out.println(strTimestamp + " [Original String]");

        String format = "yyyy-MM-dd HH:mm:ss.SSS";
        System.out.println(format + " [Format used]");
        java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(format);

        // Convert String to Date:
        java.util.Date date = formatter.parse(strTimestamp);
        long time = date.getTime();
        System.out.println(formatter.format(time) + " [Date#getTime() with same format]");

        java.sql.Timestamp timestamp = new java.sql.Timestamp(time);
        System.out.println(timestamp + " [Timestamp]");
    }
}

上面的代码提供以下输出:

TEST 1: 
1957-04-27 00:00:00.01 [Original String]
yyyy-MM-dd HH:mm:ss.SS [Format used]
1957-04-27 00:00:00.01 [Date#getTime() with same format]
1957-04-27 00:00:00.001 [Timestamp]

TEST 2: 
1957-04-27 00:00:00.001 [Original String]
yyyy-MM-dd HH:mm:ss.SSS [Format used]
1957-04-27 00:00:00.001 [Date#getTime() with same format]
1957-04-27 00:00:00.001 [Timestamp]

TEST 1中,我期望[Original String][Date#getTime() with same format][Timestamp]都具有相同的输出,就像在TEST 2处一样.

In TEST 1 I was expecting the [Original String], [Date#getTime() with same format] AND [Timestamp] to all have the same output just like at TEST 2.

为什么TEST 1中的[Timestamp]与日期相比有一个额外的零?

Why does the [Timestamp] in TEST 1 have an extra zero compared to the Date?

推荐答案

tl; dr

您的旧代码和问题现在就没有意义了.改用 java.time 类.

LocalDateTime.parse( 
    "1957-04-27 00:00:00.01".replace( " " , "T" ) 
).toString()

java.time

您正在使用的麻烦的java.util.Datejava.sql.Timestamp类现在已被遗留,由 java.time 类取代.

java.time

The troublesome java.util.Date and java.sql.Timestamp classes you are using are now legacy, supplanted by the java.time classes.

您的输入字符串接近标准ISO 8601格式.通过使用T替换中间的SPACE进行编译.解析/生成字符串时,java.time类默认使用ISO 8601格式.

Your input string is close to standard ISO 8601 format. Comply by replacing the SPACE in the middle with a T. The java.time classes use ISO 8601 formats by default when parsing/generating strings.

String input = "1957-04-27 00:00:00.01".replace( " " , "T" ) ;

解析为 LocalDateTime 对象,因为您的输入缺少任何时区或UTC偏移量.

Parse as a LocalDateTime object given that your input lacks any indicator of time zone or offset-from-UTC.

LocalDateTime ldt = LocalDateTime.parse( input ) ;

要生成ISO 8601格式的字符串,只需调用toString().默认格式设置器根据需要使用0到3个三位数字的组来显示小数秒,直到十进制小数的九位数为纳秒.

To generate a string in ISO 8601 format, simply call toString(). The default formatter uses 0-3 groups of three digits as needed to display the fractional second, up to the nine digits of decimal fraction for nanoseconds.

String output = ldt.toString() ;

1957-04-27T00:00:00.010

1957-04-27T00:00:00.010

您可以使用JDBC 4.2和更高版本直接将LocalDateTime对象与类型为TIMESTAMP WITHOUT TIME ZONE的数据库列交换.

You can exchange your LocalDateTime object directly with your database column of type TIMESTAMP WITHOUT TIME ZONE using JDBC 4.2 and later.

myPreparedStatement.setObject( … , ldt ) ;

和检索.

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;


关于 java.time

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


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time 项目,现在位于<一个href ="https://en.wikipedia.org/wiki/Maintenance_mode" rel ="nofollow noreferrer">维护模式,建议迁移到要了解更多信息,请参见 Oracle教程 .并在Stack Overflow中搜索许多示例和说明.规范为 JSR 310 .

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

在哪里获取java.time类?

Where to obtain the java.time classes?

  • Java SE 8 Java SE 9 和更高版本
    • 内置.
    • 具有捆绑的实现的标准Java API的一部分.
    • Java 9添加了一些次要功能和修复.
    • Java SE 8, Java SE 9, and later
      • Built-in.
      • Part of the standard Java API with a bundled implementation.
      • Java 9 adds some minor features and fixes.
      • Later versions of Android bundle implementations of the java.time classes.
      • For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

      > ThreeTen-Extra 项目扩展了java.time与其他班级.该项目为将来可能在java.time中添加内容提供了一个试验场.您可能会在这里找到一些有用的类,例如 Interval YearWeek YearQuarter 更多.

      这篇关于从java.util.Date到java.sql.Timestamp时添加了无法解释的零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆