【问题标题】:Time.valueOf method returning wrong valueTime.valueOf 方法返回错误值
【发布时间】:2020-08-10 09:41:48
【问题描述】:

我使用 Time.valueOf 方法将 String "09:00:00" 转换为 Time 对象,如下所示:Time.valueOf (LocalTime.parse("09:00:00"))。

当我调用 getTime() 来显示我得到的值时:28800000 毫秒而不是 32400000 毫秒(由计算器计算得出)。

我使用 Time.value Of 时是否出错?因为我不明白为什么我得到了错误的值。

谢谢。

【问题讨论】:

    标签: java time localtime


    【解决方案1】:

    坚持 java.time.LocalTime

    我建议您坚持使用现代 Java 日期和时间 API java.time 中的LocalTime,不要使用java.sql.Time。后一个类的设计很差,确实是在设计已经很差的java.util.Date 类之上的一个真正的hack。幸运的是,它也已经过时了。曾几何时,我们需要一个 Time 对象来将一天中的时间存储到数据类型为 time 的数据库列中,或者将时间传输到使用该数据类型的 SQL 查询中。从 JDBC 4.2 开始,情况不再如此。现在您的 JDBC 驱动程序接受 LocalTime 对象并将其时间值传递给数据库。

    因此,如果您有一个字符串,请按照您已经做过的方式将其解析为 LocalTime 对象:

        LocalTime time = LocalTime.parse("09:00:00");
    

    如果你不需要遍历一个字符串,你可以使用of工厂方法得到同样的结果,例如:

        LocalTime time = LocalTime.of(9, 0);
    

    我不知道您为什么要将其转换为毫秒,但您可以:

        int milliOfDay = time.get(ChronoField.MILLI_OF_DAY);
        System.out.println(milliOfDay);
    

    输出是:

    32400000

    这是您所说的预期值。

    要将LocalTime 插入数据库:

        PreparedStatement ps = yourDatabaseConnection.prepareStatement(
                "insert into your_table(your_time_col) values (?)");
        ps.setObject(1, time);
        int rowsInserted = ps.executeUpdate();
    

    注意使用setObject(),而不是setTime()

    如果您确实需要 Time 对象来处理您现在不想升级的旧版 API,那么您所做的转换是正确的。

    你的预期是错误的,你的转化是正确的

    我在使用 Time.value Of 时是否出错?因为我不 了解为什么我得到错误的值。

    不,反过来。你没有犯错。在这种情况下,您得到了正确的值。这是Time 在欺骗你的糟糕而令人困惑的设计(我说过你不应该使用那个类)。我不确定它是否已记录在案,但 Time.valueOf (LocalTime.parse("09:00:00")) 为您提供了一个 Time 对象,该对象在内部保存 1970 年 1 月 1 日 09:00 的时间点 在您的 JVM 时区。从您得到的毫秒值 28 800 000 来看,这个时间似乎等于 08:00 UTC。您的时区是 1970 年冬天的 UTC 偏移 +01:00 吗? getTime() 方法返回自 1970 年 1 月 1 日 00:00 UTC 以来的毫秒数。

    【讨论】:

      【解决方案2】:

      这是由时区问题引起的。如果你这样做了

      TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
      

      在您的代码之前,您将得到 32400000,正如您所期望的那样。

      Time.valueOf (LocalTime.parse("09:00:00")) 假设 9 位于您的本地时区,因此它将其转换为 UTC。

      例如,如果时区是 "Asia/Jerusalem"(您可以使用 TimeZone.setDefault(TimeZone.getTimeZone("Asia/Jerusalem")); 模拟它,它是 1970 年 1 月 1 日的 UTC+2,它会将 9 点钟转换为 7 点钟。您可以用 @ 看到它987654327@

      在有关旧 java time api 的问题中,我必须给你一个强制性建议,始终只使用modern post java8 api。

      【讨论】:

      • 就我自己的理解而言:java.sql.timejava.util.date 的一个薄包装(上面写着here)。而date 使用的是本地的 TZ……这是问题的根源吗?
      • @andrewjames 我添加了解释。
      猜你喜欢
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-08
      相关资源
      最近更新 更多