Time.valueOf方法返回错误的值

3

我使用Time.valueOf方法将字符串"09:00:00"转换成时间对象,如下所示:Time.valueOf(LocalTime.parse("09:00:00"))。

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

我在使用Time.valueOf时是否犯了错误?因为我不明白为什么会得到错误的值。

谢谢。

2个回答

3

这是由于时区问题引起的。如果您进行

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

在你的代码中,你会得到预期的32400000。

Time.valueOf (LocalTime.parse("09:00:00")) 假设九点在你所在的本地时区,因此将其转换为UTC时间。

例如,如果时区是"亚洲/耶路撒冷"(您可以使用TimeZone.setDefault(TimeZone.getTimeZone("Asia/Jerusalem"));进行模拟),它在1970年1月1日UTC+2时将9点转换为7点。您可以使用System.out.println(time.toGMTString());查看它。

像往常一样,在涉及旧的Java时间API的问题中,我必须强烈建议您始终仅使用现代的post java8 api。


为了自己的理解:java.sql.time是对java.util.date的轻量级封装(在这里[https://docs.oracle.com/javase/7/docs/api/java/sql/Time.html#valueOf(java.lang.String))有说明)。而`date`使用本地时区... 那么这是否是问题的源头? - andrewJames
@andrewjames 我添加了一个解释。 - Oleg

2

坚持使用java.time.LocalTime

我建议你坚持使用来自现代Java日期和时间API的LocalTime,而不是使用java.sql.Time。后者设计不佳,实际上是在已经设计不佳的java.util.Date类的基础上进行了一次真正的黑客攻击。幸运的是它已经过时了很久。曾经我们需要一个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以来的毫秒数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接