栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在Java中使用尾随小数点将十进制时间戳转换为日期

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在Java中使用尾随小数点将十进制时间戳转换为日期

java.time

使用说明中的示例:

时间戳-C50204EC EC42EE92相当于2004年9月27日UTC。

    Instant epoch = OffsetDateTime.of(1900, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant();    BigInteger timeStamp = new BigInteger("C50204ECEC42EE92", 16);    // To get the whole part and the fraction right, divide by 2^32    double secondsSince1900 = timeStamp.doublevalue() / 0x1_0000_0000L;    // Convert seconds to nanos by multiplying by 1 000 000 000    Instant converted = epoch.plusNanos(Math.round(secondsSince1900 * 1_000_000_000L));    System.out.println(converted);

输出为:

2004-09-27T03:18:04.922896384Z

偏离了85纳秒。更好的浮点算法可能会做得更好。编辑:不可避免的是,由于原始时间戳的分辨率为2 ^ -32秒,精度是纳秒(10 ^
-9秒)分辨率的4倍以上,因此精度的损失是不可避免的

Instant

Calendar
您尝试使用的类设计总是很差,现在已经过时了。取而代之的是,我按照其中的建议,我正在使用java.time,这是现代的Java日期和时间API。编辑:为了进行比较
Calendar
,分辨率为毫秒,因此充其量只能给您带来精度上的损失。

编辑:更精确的数学

我不能让85纳秒成为现实。这是一个尽可能保持精度并给出预期结果的版本:

    BigDecimal timeStamp = new BigDecimal(new BigInteger("C50204ECEC42EE92", 16));    // To get the whole part and the fraction right, divide by 2^32    BigDecimal bit32 = new BigDecimal(0x1_0000_0000L);    BigDecimal secondsSince1900 = timeStamp.divide(bit32);    // Convert seconds to nanos by multiplying by 1 000 000 000; round to long    long nanosSince1900 = secondsSince1900.multiply(new BigDecimal(TimeUnit.SECONDS.tonanos(1))) .setScale(0, RoundingMode.HALF_UP) .longValueExact();    Instant converted = epoch.plusNanos(nanosSince1900);

2004-09-27T03:18:04.922896300Z

1纳米太多?这是因为我在对的调用中使用了上舍入四舍五入

setScale
。相反,如果我截断(使用
RoundingMode.FLOOR
),则可以从解释中得到确切的结果。因此,我的版本不会比他们的版本失去更多的精度。

链接

Oracle教程:Date
Time,说明如何使用java.time。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/431360.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号