Não é possível converter de java Double para java Date

Estou tendo um problema com a conversão de um duplo para um object de data Java no formato: aaaa-MM-dd HH: mm: ss

Eu tentei converter esse valor duplo em um valor longo e instanciar um object Date com o resultado, mas recebi erros dizendo que não é possível converter de double para long.

meus valores duplos de data e hora estão neste formato:

1.511554592277516E9

Alguém pode me ajudar com este problema por favor, obrigado antecipadamente.

Supondo que esse valor de ponto flutuante esteja alguns segundos após a Unix Epoch de 1 de janeiro de 1970 às 0:00 GMT, isso fornecerá uma conversão para um LocalDateTime com esse deslocamento:

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

Deixo convertendo isso para uma Date como um exercício para o leitor.

Seu valor de ponto flutuante, 1.511554592277516E9 , sem dúvida denota segundos desde a época de 1 de janeiro de 1970 à meia-noite UTC, com precisão de microssegundos: 1 511 554 592 segundos e 277 516 microssegundos (milionésimos de segundo).

Eu sugiro usar java.time , a moderna API de data e hora Java, também conhecida como JSR-310, para isso. É muito melhor trabalhar com a class Date desatualizada e com os amigos, além de oferecer precisão de nanossegundos (a Date tem apenas precisão de milissegundos, portanto você perderia a precisão se convertendo em um). Mais especificamente, vou primeiro criar um object java.time.Instant (a conversão para outros tipos de data e hora será fácil, vou tocar em um exemplo no final).

Conseguir a precisão total através de um Instant requer um pequeno pensamento. Eu joguei um pouco com double e long , mas percebi que (1) double não tem a precisão completa requerida, os nanossegundos não estarão certos (2) convertendo para um long hold de nanossegundos (não é o único caminho, mas certamente o mais fácil ) criará um “problema do ano 2262”, portanto, se você estiver lidando com datas em um futuro distante, isso não funcionará. Em qualquer caso, acho que a solução fácil e segura é usar BigDecimal para a matemática necessária antes de alimentar os números em um Instant .

  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); 

Isso imprime:

 2017-11-24T20:16:32.277516Z 

A data impressa é em UTC. Se o valor for o esperado, devo dizer que confirma que seu valor de ponto flutuante foi de fato segundos desde a época.

Você solicitou uma data e hora no formato aaaa-MM-dd HH: mm: ss. Você precisará decidir em qual fuso horário deseja a data e hora. Os objects de data não possuem um formato, portanto, você também precisará obter o formato em uma string. Por exemplo:

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

Isso imprime

 2017-11-24 12:16:32 

Você substitui seu fuso horário desejado, é claro. atZone() converte o Instant em um ZonedDateTime , outra class frequentemente usada de java.time .

EDIT : Caso você não queira se preocupar com BigDecimal , você aceita uma pequena imprecisão e / ou recebe seu valor como um double em vez de uma string, aqui está uma alternativa em menos linhas de código:

  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); 

Neste caso particular, ele fornece exatamente o mesmo resultado, até o nanossegundo. Não tenho certeza se com outras inputs, os microssegundos podem acabar imprecisos, mas, por outro lado, se você receber um double (não uma string), não há nada que você possa fazer sobre isso de qualquer maneira.