Obtendo "unixtime" em Java

258

Date.getTime () retorna milissegundos desde 1 de janeiro de 1970. O tempo unix é segundos desde 1 de janeiro de 1970. Normalmente não codigo em java, mas estou trabalhando em algumas correções. Eu tenho:

Date now = new Date();      
Long longTime = new Long(now.getTime()/1000);
return longTime.intValue();

Existe uma maneira melhor de obter unixtime em java?

Gary Richardson
fonte
27
Desde que você lançou um int, você introduziu o problema do ano 2038 (o equivalente ao Y2K para Unix). É quando a época do Unix atinge 2 bilhões e passa para o negativo. A correção é mudar para o Unix de 64 bits. O equivalente em Java é deixá-lo por muito tempo.
John M
1
Sim, eu estou ciente disso. O código com o qual está interagindo está esperando um int de 32 bits por tempo unix.
Gary Richardson
158
2038 está chegando.
Pacerier 13/01/12
Existe um nome ou padrão adequado para currentTimeMillis? Costumo me referir a ele na minha documentação como a versão em milissegundos do tempo UNIX.
Tom
1
Se você deseja que seu software sobreviva ao estouro, use long, não int. Não há realmente nenhuma razão para usar intpara um carimbo de data / hora, a menos que você esteja usando uma granularidade diferente como 1 segundo = 4 segundos etc. Ou isso, ou oculte seu código para que as gerações futuras não possam ver o quão incompetente você era.
bryc

Respostas:

475

Evite a criação do objeto Data com System.currentTimeMillis () . Uma divisão por 1000 leva você à época do Unix.

Como mencionado em um comentário, você normalmente deseja um longo primitivo (minúsculo-l longo) e não um objeto em caixa longo (maiúscula-L longo) para o tipo da variável unixTime.

long unixTime = System.currentTimeMillis() / 1000L;
John M
fonte
3
Também considere o uso primitivo long em vez de autoboxing para Long, a menos que você quer lidar com o número como um objeto (como colocá-lo em uma Collection), evita novamente a criação de objetos desnecessários
brabster
9
O Java de 32 bits int corresponde a plataformas de 32 bits (e o problema do ano 2038). As plataformas de 64 bits usam um tipo de dados time_t maior. Java se esquivou dessa bala usando o tempo que retornou para System.currentTimeMillis (). Se você converter para int, estará reintroduzindo o problema do ano 2038. Veja en.wikipedia.org/wiki/Year_2038_problem#Solutions
John M
1
Acho que você está enganado em um ponto: não há diferença entre letras minúsculas "L" e letras maiúsculas ao usá-las em literais numéricos como este. docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.1
matt forsythe
5
A discussão sobre maiúsculas (esclarecida acima) foi sobre o tipo de dados. Instância da classe primitiva "long" vs "java.lang.Long". Você está falando sobre a letra do sufixo no literal longo, que eu concordo que pode ser maiúscula ou minúscula. Embora letras minúsculas "l" pareça muito com o dígito "1", é muito mais legível usar letras maiúsculas "L".
John M
1
Clique no link para a documentação. O retorno é definido como o número de milissegundos desde 1/1/1970 no fuso horário UTC. Você quer fusos horários? Veja java.util.Calendar.
John M
273

O Java 8 adicionou uma nova API para trabalhar com datas e horas. Com o Java 8 você pode usar

import java.time.Instant
...
long unixTimestamp = Instant.now().getEpochSecond();

Instant.now()retorna um instante que representa a hora atual do sistema. Com getEpochSecond()você obtém os segundos da época (tempo unix) a partir do Instant.

micha
fonte
4
Qual é a diferença entre Instant.now().getEpochSecond(), new Date().getTime()eSystem.currentTimeMillis()
SohamC 2/16/16
2
Uma diferença é que o primeiro está em segundos, enquanto os dois últimos estão em milissegundos. Pode ou não haver outros.
Super_aardvark
3
import java.time.Instantse você estiver em Scala
akauppi
4
Confira neste site, bem como para descrição detalhada ... gostou .. currentTimeMillis
Subroto
1
Observe que você não pode usar esse método com níveis de API do Android mais antigos.
Ali Nadalizadeh