【问题标题】:Converting java.sql.Timestamp to java.util.Calendar without losing precision将 java.sql.Timestamp 转换为 java.util.Calendar 而不会丢失精度
【发布时间】:2012-10-26 05:28:09
【问题描述】:

我正在尝试从数据库中获取时间戳值,将它们转换为日历,然后将它们转换回时间戳,但它们失去了精度。

这是重现问题的代码

import java.sql.Timestamp;
import java.util.Calendar;

public class Test {
    public static void main(String[] args)
    {
        Timestamp timestamp = new Timestamp(112, 10, 5, 15, 39, 11, 801000000);
        System.out.println("BEFORE "+timestamp.toString());
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timestamp.getTime());
        timestamp = new Timestamp(calendar.getTimeInMillis());
        System.out.println("AFTER "+timestamp.toString());
    }
}

这是转换的示例结果

BEFORE 2012-10-18 14:30:13.362001
AFTER 2012-10-18 14:30:13.362

它失去了精确性。 我该怎么做才能保持十进制值不变?

【问题讨论】:

  • 我已经在我的 ide 中尝试过,但我没有得到这样的结果,每次打印都一样 - Calendar calendar = Calendar.getInstance(); Timestamp timestamp = new Timestamp(new Date().getTime()); System.out.println("1 -> "+timestamp); // Thread.currentThread().sleep(1000); calendar.setTimeInMillis(timestamp.getTime()); timestamp = new Timestamp(calendar.getTimeInMillis()); System.out.println("2 -> "+timestamp);
  • 你能提供更多的上下文吗?你从哪里得到这些时间戳,你如何输出它们?
  • 我已经更新了例子,很抱歉之前的错误结果是我的错。

标签: java calendar timestamp


【解决方案1】:

java.time

在 Java 8 及更高版本中,我们现在有了一个解决方案:内置了新的java.time 框架。由JSR 310 定义,受Joda-Time 启发,由ThreeTen-Extra 项目扩展。

这个新框架具有nanosecond 分辨率。这足以处理旧的 java.util.Date 值、Joda-Time 值,它们都是milliseconds。而且处理Postgres等一些数据库使用的microseconds就足够了。某些数据库(例如 H2)使用纳秒。所以 java.time 可以处理这一切,或者至少可以处理所有主流情况。唯一的例外是利基科学或工程情况。

在 Java 8 中,旧类获得了与 java.time 相互转换的新方法。在 java.sql.Timestamp 上使用新的 toInstantfromInstant 方法。 Instant 类包含从纪元开始的纳秒计数,1970 UTC 的第一个时刻(基本上,请参阅类文档了解详细信息)。

您可以从Instant 获取ZonedDateTime 对象。

java.sql.Timestamp ts = myResultSet.getTimestamp( 1 );
Instant instant = ts.toInstant();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

【讨论】:

    【解决方案2】:

    您以 毫秒 为单位设置时间,但您的输入精度以 微秒 为单位,因此您当然会丢失任何比毫秒更精细的精度。

    日历不支持比毫秒更精细的粒度。没有变通方法。

    【讨论】:

    • 而且也没有替代课?
    • @William JodaTime 是通常的响应,但它也只支持毫秒。您的要求有点不寻常 - 考虑使用毫秒粒度(像其他人一样)
    猜你喜欢
    • 2013-11-14
    • 2010-10-29
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 2018-05-26
    • 2015-12-04
    • 2011-08-24
    相关资源
    最近更新 更多