Como posso obter a contagem de milissegundos desde a meia-noite da corrente?

125

Note, eu NÃO quero milis da época. Quero o número de milissegundos atualmente no relógio.

Por exemplo, eu tenho esse pedaço de código.

Date date2 = new Date(); 
Long time2 = (long) (((((date2.getHours() * 60) + date2.getMinutes())* 60 ) + date2.getSeconds()) * 1000);

Existe uma maneira de obter milissegundos com data? Há outra maneira de fazer isso?

Nota: System.currentTimeMillis() dá-me milis da época que não é o que estou procurando.

Lemonio
fonte
2
Você quer dizer "milissegundos no segundo", para que o valor esteja sempre no intervalo [0, 999], correto? @thinksteep leu a última frase.
Matt Bola
@Lemonio Dar um exemplo tornaria sua pergunta mais clara.
Basil Bourque
Para sua informação, as antigas classes problemáticas de data e hora, como java.util.Dateagora são herdadas , substituídas pelas classes java.time .
Basil Bourque
Para sua informação, as antigas classes problemáticas de data e hora, como java.util.Dateagora são herdadas , substituídas pelas classes java.time . Consulte o Tutorial da Oracle .
Basil Bourque
1
O JEP 150 do @ChrisNeve, aprovado por Brian Goetz , o JSR 310 adotou por unanimidade , um artigo técnico publicado pela Oracle e a substituição do antigo Tutorial do Oracle para data e hora pelo novo Tutorial java.time .
Basil Bourque

Respostas:

198

Você quer dizer?

long millis = System.currentTimeMillis() % 1000;

BTW Windows não permite o horário de 1969

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.
Peter Lawrey
fonte
8
Observe que se você voltar no tempo para antes da época do Unix, isso fornecerá um valor negativo, enquanto o uso c.get(Calendar.MILLISECOND)não deveria. Pense sempre nos casos de canto!
21413 Jon Skeet
e se alguém define um fuso horário não na segunda borda ou adiciona um salto milissegundos Isso quebra =)).
Markus Mikkolainen
35
Java não suporta viagens no tempo.
R. Martinho Fernandes
1
@MarkusMikkolainen: Não, System.currentTimeMillis()não é afetado pelos fusos horários.
21416 Jon Skeet
1
@ PeterLawrey: Bem, pode ou não. Depende da implementação. Dos documentos para Data: "Um segundo é representado por um número inteiro de 0 a 61; os valores 60 e 61 ocorrem apenas por segundos bissextos e, mesmo assim, apenas em implementações Java que realmente rastreiam corretamente os segundos bissextos. Devido à maneira pela qual o salto No momento em que são introduzidos segundos, é extremamente improvável que dois segundos bissextos ocorram no mesmo minuto, mas essa especificação segue as convenções de data e hora da ISO C. "
21816 Jon Skeet
25

Usar calendário

Calendar.getInstance().get(Calendar.MILLISECOND);

ou

Calendar c=Calendar.getInstance();
c.setTime(new Date()); /* whatever*/
//c.setTimeZone(...); if necessary
c.get(Calendar.MILLISECOND);

Na prática, acho que quase sempre será igual a System.currentTimeMillis ()% 1000; a menos que alguém tenha um milissegundo de salto ou algum calendário seja definido com uma época que não esteja no segundo limite.

Markus Mikkolainen
fonte
O calendário já é hora atual, por padrão, e não há s em MILLISECOND.
precisa saber é o seguinte
17
Calendar.getInstance().get(Calendar.MILLISECOND);
kgautron
fonte
14

tl; dr

Você pede a fração de segundo do tempo atual como um número de milissegundos ( sem contar da época).

Instant.now()                               // Get current moment in UTC, then…
       .get( ChronoField.MILLI_OF_SECOND )  // interrogate a `TemporalField`.

2017-04-25T03: 01: 14.113Z → 113

  1. Obtenha o segundo fracionário em nanossegundos (bilhões).
  2. Divida por mil para truncar em milissegundos (milhares).

Veja este código executado ao vivo em IdeOne.com .

Usando java.time

A maneira moderna é com as classes java.time.

Capture o momento atual no UTC.

Instant.now()

Use o Instant.getmétodo para interrogar o valor de a TemporalField. No nosso caso, o TemporalFieldque queremos é ChronoField.MILLI_OF_SECOND.

int millis = Instant.now().get( ChronoField.MILLI_OF_SECOND ) ;  // Get current moment in UTC, then interrogate a `TemporalField`.

Ou faça as contas você mesmo.

É mais provável que você esteja solicitando um fuso horário específico. É provável que a fração de segundo seja igual à de Instantmas há tantas anomalias com fusos horários que hesito em fazer essa suposição.

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

Interrogar pelo segundo fracionário. A pergunta fazia milissegundos , mas as classes java.time usam uma resolução mais fina de nanossegundos . Isso significa que o número de nanossegundos variará de 0 a 999.999.999.

long nanosFractionOfSecond = zdt.getNano();

Se você realmente deseja milissegundos, trunque os dados mais finos dividindo por um milhão. Por exemplo, meio segundo é 500.000.000 nanossegundos e também é 500 milissegundos.

long millis = ( nanosFractionOfSecond / 1_000_000L ) ;  // Truncate nanoseconds to milliseconds, by a factor of one million.

Sobre java.time

A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como java.util.Date, Calendar, e SimpleDateFormat.

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

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

Onde obter as classes java.time?

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

Basil Bourque
fonte
13

Eu tentei alguns acima, mas eles parecem redefinir @ 1000

Este definitivamente funciona, e também deve levar o ano em consideração

long millisStart = Calendar.getInstance().getTimeInMillis();

e faça o mesmo para o horário final, se necessário.

Assistente de alto calibre
fonte
1
Respondendo a pergunta errada. Isso é o milésimo atual da época, não o milis parte do tempo atual.
Sean Van Gorder
5
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

Sexta-feira, 04 de abril 14:27:05 PDT 2014

omarflorez
fonte
3

Joda-Time

Eu acho que você pode usar o Joda-Time para fazer isso. Dê uma olhada na DateTimeclasse e seu getMillisOfSecondmétodo. Algo como

int ms = new DateTime().getMillisOfSecond() ;
RNJ
fonte
Erro de compilação: " getMillis()possui acesso protegido"; precisa usar em seu get()lugar. Observe também que isso new DateTime(new Date())é equivalente a escrever simplesmente new DateTime().
Jonik
O método millisOfSecondacessa um objeto e a chamada adicional getextrai uma primitiva intdesse objeto. Você pode recolher as duas chamadas usando o método getter de conveniência getMillisOfSecond,. O Joda-Time segue esse padrão para muitas de suas propriedades.
Basil Bourque
1
Para sua informação, o projeto Joda-Time agora está no modo de manutenção , com a equipe aconselhando a migração para as classes java.time .
Basil Bourque
0

No Java 8, você pode simplesmente fazer

ZonedDateTime.now().toInstant().toEpochMilli()

retorna: o número de milissegundos desde a época de 1970-01-01T00: 00: 00Z

Aniket Thakur
fonte
1
[A] Não é isso que a pergunta pediu. Diz expressamente que eles não querem uma contagem de milissegundos desde a data de referência da época. [B] Você pode encurtar isso ao largar o ZonedDateTime:Instant.now().toEpochMilli()
Basil Bourque
0

Eu fiz o teste usando java 8 Não importa a ordem em que o construtor sempre leva 0 milissegundos e a concatenação entre 26 e 33 milissegundos abaixo e a iteração de uma concatenação de 1000

Espero que ajude a experimentá-lo com seu ide

public void count() {

        String result = "";

        StringBuilder builder = new StringBuilder();

        long millis1 = System.currentTimeMillis(),
            millis2;

        for (int i = 0; i < 1000; i++) {
            builder.append("hello world this is the concat vs builder test enjoy");
        }

        millis2 = System.currentTimeMillis();

        System.out.println("Diff: " + (millis2 - millis1));

        millis1 = System.currentTimeMillis();

        for (int i = 0; i < 1000; i++) {
            result += "hello world this is the concat vs builder test enjoy";
        }

        millis2 = System.currentTimeMillis();

        System.out.println("Diff: " + (millis2 - millis1));
    }
Aldo Infanzon
fonte
0

Java 8:

LocalDateTime toDate = LocalDateTime.now();
LocalDateTime fromDate = LocalDateTime.of(toDate.getYear(), toDate.getMonth(), 
toDate.getDayOfMonth(), 0, 0, 0);
long millis = ChronoUnit.MILLIS.between(fromDate, toDate);
Efren Villamagua
fonte
1
Não funciona em alguns fusos horários. Em algumas zonas, em algumas datas, o dia pode não começar às 00:00:00. E o dia pode não durar 24 horas, pode adicionar ou pular algumas horas ou minutos. A LocalDateTimeclasse não pode representar um momento, sem qualquer conceito de fuso horário ou deslocamento do UTC e, portanto, não pode rastrear esses problemas de fuso horário.
Basil Bourque
0

Você pode usar a classe java.util.Calendar para obter tempo em milissegundos. Exemplo:

Calendar cal = Calendar.getInstance();
int milliSec = cal.get(Calendar.MILLISECOND);
// print milliSec

java.util.Date date = cal.getTime();
System.out.println("Output: " +  new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(date));
Rajat
fonte