如何在Java中将十进制时间戳转换为带有尾随小数的日期

我一直在试图弄清楚如何将时间戳转换为日期,但末尾带有小数点,例如:时间戳 - 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); 

我的想法是日历可能不可能,所以我必须从头开始,但我不知道如何去做。


墨色风雨
浏览 137回答 1
1回答

摇曳的蔷薇

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 纳秒。可能更好的浮点运算可以做得更好。编辑:由于原始时间戳的分辨率为 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.922896300Z1纳米太多了?这是因为我在调用setScale. 相反,如果我截断(使用RoundingMode.FLOOR),我会从解释中得到确切的结果。所以我的版本不会比他们的更精确。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java