亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在Java中將十進制時間戳轉換為帶有尾隨小數的日期

如何在Java中將十進制時間戳轉換為帶有尾隨小數的日期

墨色風雨 2022-07-20 19:30:58
我一直在試圖弄清楚如何將時間戳轉換為日期,但末尾帶有小數點,例如:時間戳 - C50204EC EC42EE92 相當于 2004 年 9 月 27 日 03:18:04.922896299 UTC。時間戳格式包括作為跨越 136 年的字段的前 32 位無符號秒和解析 232皮秒的 32 位小數字段。在時間戳格式中,時代 0 的主要紀元或基準日期是 UTC 1900 年 1 月 1 日 0 時,此時所有位都為零。到目前為止,這是我為我的代碼編寫的內容:    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); 我的想法是日歷可能不可能,所以我必須從頭開始,但我不知道如何去做。
查看完整描述

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),我會從解釋中得到確切的結果。所以我的版本不會比他們的更精確。



查看完整回答
反對 回復 2022-07-20
  • 1 回答
  • 0 關注
  • 162 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號