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

我一直在尝试找出如何将时间戳转换为日期,但末尾带有小数,因此,例如:时间戳-C50204EC

EC42EE92相当于2004年9月27日03:18:04.922896299 UTC。

时间戳格式包括第一个32位无符号秒,该字段跨越136年,而32位小数字段解析为232

皮秒。在时间戳格式中,当所有位均为零时,原始时期或时代0的基准日期为1900

UTC 1月1日0 h。

到目前为止,这是我为代码编写的内容:

    BigDecimal bi = new BigDecimal("1096255084000");

double decimal_timestamp = bi.doubleValue();

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS");

formatter.setTimeZone(TimeZone.getTimeZone("UTC"));

Calendar calendar = Calendar.getInstance();

calendar.setTimeInMillis(decimal_timestamp);

String date = formatter.format(calendar.getTime());

System.out.println(decimal_timestamp + " = " + date);

我的想法是,使用日历可能无法实现,因此我必须从头开始,但是我不知道该怎么做。

回答:

回答:

使用说明中的示例:

时间戳-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。

以上是 如何在Java中使用尾随小数点将十进制时间戳转换为日期 的全部内容, 来源链接: utcz.com/qa/409931.html

回到顶部