从java.util.Date到java.sql.Timestamp

时间:2017-02-21 16:04:40

标签: java date timestamp unix-timestamp java.util.date

请考虑以下测试代码(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相同的输出。

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

2 个答案:

答案 0 :(得分:1)

TL;博士

您的旧代码和问题现在没有实际意义。请改用 java.time 类。

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

java.time

您正在使用的麻烦的java.util.Datejava.sql.Timestamp类现在已经遗留下来,取而代之的是 java.time 类。

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

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

解析为LocalDateTime对象,因为您的输入缺少任何时区指示或从UTC偏移。

LocalDateTime ldt = LocalDateTime.parse( input ) ;

要生成ISO 8601格式的字符串,只需调用toString()即可。默认格式化程序根据需要使用0-3组三位数来显示小数秒,最多小数位数的九位数为纳秒。

String output = ldt.toString() ;
  

1957-04-27T00:00:00.010

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

myPreparedStatement.setObject( … , ldt ) ;

并检索。

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

关于 java.time

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

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:0)

您在两种测试方法中打印时都忘记格式化时间戳值 - 第一次测试成功的事实只是巧合。

变化:

System.out.println(timestamp + " [Timestamp]");

要:

System.out.println(formatter.format(timestamp) + " [Timestamp]");

你应该得到你期望的结果。