Como posso encontrar a quantidade de segundos decorridos desde a meia-noite com o Java?

Preciso de uma function que me dê quantos segundos se passaram desde a meia-noite. Eu estou usando atualmente System.currentTimeMillis() mas me dá o timestamp como UNIX.

Seria um bônus para mim se eu conseguisse os milissegundos também.

Se você estiver usando Java> = 8, isso é feito facilmente:

 ZonedDateTime now = ZonedDateTime.now(); ZonedDateTime midnight = now.atStartOfDay() Duration duration = Duration.between(midnight, now); long secondsPassed = duration.getSeconds(); 

Se você estiver usando o Java 7 ou menos, terá que obter a data da meia-noite pelo Calendário e, em seguida, subtrair.

 Calendar c = Calendar.getInstance(); long now = c.getTimeInMillis(); c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.MINUTE, 0); c.set(Calendar.SECOND, 0); c.set(Calendar.MILLISECOND, 0); long passed = now - c.getTimeInMillis(); long secondsPassed = passed / 1000; 

java.time

Usando o framework java.time incorporado no Java 8 e posterior. Veja o tutorial .

 import java.time.LocalTime import java.time.ZoneId LocalTime now = LocalTime.now(ZoneId.systemDefault()) // LocalTime = 14:42:43.062 now.toSecondOfDay() // Int = 52963 

É uma boa prática especificar o ZoneId , mesmo se você quiser um padrão.

tl; dr

 Duration.between( todayStart , now ) .getSeconds() 

java.time

O Java 8 e mais recente tem o framework java.time ativado.

Usando ZonedDateTime e fuso horário, estamos lidando com anomalias como o horário de verão (DST) . Por exemplo, nos Estados Unidos, um dia pode ter 23, 24 ou 25 horas de duração. Então o tempo até amanhã pode variar de ± 1 hora de um dia para o outro.

Primeiro pegue o momento atual.

 ZoneId z = ZoneId.of( "America/Montreal" ); ZonedDateTime now = ZonedDateTime.now( z ); 

Agora extraia a parte somente de datas, uma LocalDate e use essa data para perguntar a java.time quando esse dia começou para o fuso horário desejado. Não assuma que o dia começou às 00:00:00. Anomalias como o Horário de Verão (DST) significam que o dia pode começar em outro horário, como 01:00:00.

 ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( z ); // Crucial to specify our desired time zone! 

Agora podemos obter o delta entre o momento atual e o começo de hoje. Esse período de tempo desassociado da linha do tempo é representado pela class Duration .

 Duration duration = Duration.between( todayStart , now ); 

Peça ao object Duration o número total de segundos em todo o período de tempo.

 long secondsSoFarToday = duration.getSeconds(); 

Sobre o java.time

O framework java.time está embutido no Java 8 e posterior. Essas classs substituem as antigas classs herdadas de data e hora legadas , como java.util.Date , Calendar e SimpleDateFormat .

O projeto Joda-Time , agora em modo de manutenção , aconselha a migration para as classs java.time .

Para saber mais, veja o Oracle Tutorial . E pesquise o Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

Onde obter as classs java.time?

  • Java SE 8 , Java SE 9 e posterior
    • Construídas em.
    • Parte da API Java padrão com uma implementação integrada.
    • O Java 9 adiciona alguns resources e correções menores.
  • Java SE 6 e Java SE 7
    • Grande parte da funcionalidade java.time é transferida para o Java 6 e 7 no ThreeTen-Backport .
  • Android
    • O projeto ThreeTenABP adapta o ThreeTen-Backport (mencionado acima) especificamente para o Android.
    • Veja Como usar o ThreeTenABP… .

O projeto ThreeTen-Extra estende java.time com classs adicionais. Este projeto é um campo de testes para possíveis futuras adições ao java.time. Você pode encontrar algumas classs úteis aqui como Interval , YearWeek , YearQuarter e muito mais .

O método mais simples e rápido para obter os segundos desde a meia-noite para o fuso horário atual:

Configuração única:

 static final long utcOffset = TimeZone.getDefault().getOffset(System.currentTimeMillis()); 

Se você usa o Apache Commons, você pode usar DateUtils.DAY_IN_MILLIS, caso contrário, defina:

 static final long DAY_IN_MILLIS = 24 * 60 * 60 * 1000; 

E então, sempre que você precisar do tempo …:

 int seconds = (int)((System.currentTimeMillis() + utcOffset) % DateUtils.DAY_IN_MILLIS / 1000); 

Observe que você precisará reinstalar a configuração se houver a possibilidade de que o seu programa seja executado por tempo suficiente e que ocorra a mudança no horário de verão …

Use getTime (). GetTime () em vez de getTimeInMillis () se você receber um erro sobre o calendar sendo protegido. Lembre-se de suas importações:

 import java.util.*; 

irá incluí-los enquanto estiver debugando:

  Calendar now = Calendar.getInstance(); Calendar midnight = Calendar.getInstance(); midnight.set(Calendar.HOUR_OF_DAY, 0); midnight.set(Calendar.MINUTE, 0); midnight.set(Calendar.SECOND, 0); midnight.set(Calendar.MILLISECOND, 0); long ms = now.getTime().getTime() - midnight.getTime().getTime(); totalMinutesSinceMidnight = (int) (ms / 1000 / 60); 

Usando o JodaTime você pode ligar:

 int seconds = DateTime.now().secondOfDay().get(); int millis = DateTime.now().millisOfDay().get(); 
 (System.currentTimeMillis()/1000) % (24 * 60 * 60) 

Como @secmask, se você precisar de milissegundos desde a meia-noite do GMT, tente

 long millisSinceGMTMidnight = System.currentTimeMillis() % (24*60*60*1000);