1 回答

TA貢獻1793條經驗 獲得超6個贊
java.time
使用解釋中的示例:
時間戳 - C50204EC EC42EE92 相當于 2004 年 9 月 27 日 03:18:04.922896299 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 納秒??赡芨玫母↑c運算可以做得更好。編輯:由于原始時間戳的分辨率為 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),我會從解釋中得到確切的結果。所以我的版本不會比他們的更精確。
添加回答
舉報