无法从java Double转换为java Date

我遇到了以下格式将double转换为Java日期对象的问题:yyyy-MM-dd HH:mm:ss

我试图将此double值转换为long值,然后使用结果实例化Date对象,但是我收到错误,说我无法从double转换为long。

我的timestamp double值采用以下格式:

1.511554592277516E9

请提前帮助我解决这个问题。

假设此浮点值是1970年1月1日0:00 GMT的Unix Epoch之后的秒数,这将提供到具有该偏移量的LocalDateTime的转换:

 LocalDateTime localDateTime = LocalDateTime.ofEpochSecond( Double.valueOf(1.511554592277516E9).longValue(), 0, ZoneOffset.UTC); System.out.println(localDateTime); 

我将此转换为Date作为读者的练习。

您的浮点值1.511554592277516E9无疑表示自1970年1月1日UTC时间以来的秒数,具有微秒精度:1 511 554 592秒和277 516微秒(百万分之一秒)。

我建议使用java.time ,即现代Java日期和时间API,也称为JSR-310。 使用它比过时的Date类和朋友更好,并且还提供纳秒级精度( Date只有毫秒级精度,因此如果转换为一级则会丢失精度)。 更具体地说,我将首先创建一个java.time.Instant对象(转换为其他日期时间类型将很容易,我将在最后触及一个示例)。

将完全精确度传递到Instant需要一点思考。 我用doublelong玩了一点,但实现了(1) double没有所需的全部精度,纳秒不会正确(2)转换为持有纳秒的long (不是唯一的方式,但肯定是最简单的)将创建“2262年问题”,因此如果您在遥远的未来处理日期,它将无法工作。 在任何情况下,我认为简单而安全的解决方案是在将数字输入Instant之前使用BigDecimal进行数学运算。

  String secondsSinceEpoch = "1.511554592277516E9"; BigDecimal decimalSeconds = new BigDecimal(secondsSinceEpoch); long seconds = decimalSeconds.longValue(); long nanos = decimalSeconds.subtract(BigDecimal.valueOf(seconds)) .movePointRight(9) .longValueExact(); Instant inst = Instant.ofEpochSecond(seconds, nanos); System.out.println(inst); 

这打印:

 2017-11-24T20:16:32.277516Z 

打印的日期时间以UTC为单位。 如果值是预期的,我应该说它确认你的浮点值确实是自纪元以来的秒数。

您请求格式为yyyy-MM-dd HH:mm:ss的日期时间。 您需要决定日期时间在哪个时区。 日期对象没有格式,因此您还需要获取字符串格式。 例如:

  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); System.out.println(inst.atZone(ZoneId.of("America/Vancouver")).format(formatter)); 

这打印

 2017-11-24 12:16:32 

当然,您可以替换所需的时区。 atZone()Instant转换为ZonedDateTime ,这是另一个经常使用的java.time类。

编辑 :如果你不想打扰BigDecimal ,你接受一个轻微的不准确和/或你的价值作为一个双字而不是一个字符串,这里是一个代替更少的代码行:

  double secondsSinceEpoch = 1.511554592277516E9; long longSeconds = (long) secondsSinceEpoch; long micros = Math.round((secondsSinceEpoch - longSeconds) * 1_000_000); Instant inst = Instant.ofEpochSecond(longSeconds).plus(micros , ChronoUnit.MICROS); 

在这种特殊情况下,它给出了完全相同的结果,直到纳秒。 我不确定是否使用其他输入,微秒可能最终不准确,但另一方面,如果你收到双倍(不是字符串),那么无论如何你都无能为力。