Come posso ottenere il conteggio dei millisecondi dalla mezzanotte per l'attuale?


125

Nota, NON voglio millis dall'epoca. Voglio il numero di millisecondi attualmente sull'orologio.

Quindi, ad esempio, ho questo codice.

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

C'è un modo per ottenere millisecondi con la data? c'è un altro modo per fare ciò?

Nota: System.currentTimeMillis() mi dà millis dall'epoca che non è quello che sto cercando.


2
Intendi "millisecondi nel secondo", quindi il valore è sempre nell'intervallo [0, 999], giusto? @thinksteep ha letto l'ultima frase.
Matt Ball

@Lemonio Fare un esempio renderebbe più chiara la tua domanda.
Basil Bourque,

Cordiali saluti, le vecchie e problematiche classi data-ora come java.util.Dateora sono legacy , soppiantate dalle classi java.time .
Basil Bourque,

Cordiali saluti, le vecchie classi problematiche di data e ora come java.util.Dateora sono legacy , soppiantate dalle classi java.time . Vedi Tutorial di Oracle .
Basil Bourque,

1
@ChrisNeve JEP 150 approvato da Brian Goetz , JSR 310 ha adottato all'unanimità , un articolo tecnico pubblicato da Oracle e la sostituzione del vecchio tutorial Oracle data-ora con il nuovo tutorial java.time .
Basil Bourque,

Risposte:


198

Vuoi dire?

long millis = System.currentTimeMillis() % 1000;

BTW Windows non consente il timetravel al 1969

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.

8
Si noti che se si viaggia indietro nel tempo prima dell'epoca di Unix, questo darà un valore negativo mentre l'uso c.get(Calendar.MILLISECOND)non dovrebbe. Pensa sempre alle custodie angolari!
Jon Skeet,

e se qualcuno definisce un fuso orario non sul secondo bordo o aggiunge un salto di un millisecondo questo si interrompe. =))
Markus Mikkolainen il

35
Java non supporta i viaggi nel tempo.
R. Martinho Fernandes,

1
@MarkusMikkolainen: No, System.currentTimeMillis()non è influenzato dai fusi orari.
Jon Skeet,

1
@PeterLawrey: Beh, potrebbe o no. Sta all'implementazione. Dai documenti per Date: "Un secondo è rappresentato da un numero intero compreso tra 0 e 61; i valori 60 e 61 si verificano solo per i secondi bisestili e anche solo nelle implementazioni Java che tengono effettivamente traccia dei secondi saltati. A causa del modo in cui il salto i secondi sono attualmente introdotti, è estremamente improbabile che si verifichino due secondi bisestili nello stesso minuto, ma questa specifica segue le convenzioni di data e ora per ISO C. "
Jon Skeet,

25

Usa il calendario

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

o

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

In pratica, però, penso che sarà quasi sempre uguale a System.currentTimeMillis ()% 1000; a meno che qualcuno abbia un salto di millisecondi o un calendario definito con un'epoca non su un secondo limite.


Il calendario è già l'ora corrente per impostazione predefinita e non ci sono messaggi in MILLISECOND.
kgautron,


14

tl; dr

Chiedete la frazione di secondo del tempo corrente come numero di millisecondi ( non conteggiati dall'epoca).

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

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

  1. Ottieni il secondo frazionario in nanosecondi (miliardi).
  2. Dividi per mille per troncare in millisecondi (migliaia).

Vedi questo codice eseguito dal vivo su IdeOne.com .

Utilizzando java.time

Il modo moderno è con le classi java.time.

Cattura il momento attuale in UTC.

Instant.now()

Utilizzare il Instant.getmetodo per interrogare per il valore di a TemporalField. Nel nostro caso, ciò TemporalFieldche vogliamo è ChronoField.MILLI_OF_SECOND.

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

O fai la matematica da solo.

Più probabilmente lo stai chiedendo per un fuso orario specifico. È probabile che la frazione di secondo sia la stessa di Instantma ci sono così tante anomalie con i fusi orari, esito a fare questa ipotesi.

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

Interroga per il secondo frazionario. La domanda ha richiesto millisecondi , ma le classi java.time usano una risoluzione più fine di nanosecondi . Ciò significa che il numero di nanosecondi sarà compreso tra 0 e 999.999.999.

long nanosFractionOfSecond = zdt.getNano();

Se vuoi veramente millisecondi, tronca i dati più fini dividendoli per un milione. Ad esempio, mezzo secondo è 500.000.000 di nanosecondi e anche 500 millisecondi.

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

Informazioni su java.time

Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia fastidiosi legacy classi data-time come java.util.Date, Calendar, e SimpleDateFormat.

Il progetto Joda-Time , ora in modalità manutenzione , consiglia la migrazione alle classi java.time .

Per saperne di più, consulta il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

Dove ottenere le classi java.time?

Il progetto ThreeTen-Extra estende java.time con classi aggiuntive. Questo progetto è un banco di prova per possibili aggiunte future a java.time. Si possono trovare alcune classi utili, come per esempio Interval, YearWeek, YearQuartere altro .


13

Ne ho provate alcune sopra ma sembrano ripristinare @ 1000

Questo funziona sicuramente e dovrebbe anche prendere in considerazione un anno

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

e quindi fare lo stesso per l'ora di fine, se necessario.


1
Rispondere alla domanda sbagliata. Questo è il millis corrente dell'epoca, non la parte millis del tempo corrente.
Sean Van Gorder,

5
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

Ven 04/04 14:27:05 PDT 2014


3

Joda-Time

Penso che tu possa usare Joda-Time per farlo. Dai un'occhiata alla DateTimeclasse e al suo getMillisOfSecondmetodo. Qualcosa di simile a

int ms = new DateTime().getMillisOfSecond() ;

Errore di compilazione: " getMillis()ha accesso protetto"; è necessario utilizzare get()invece. Nota anche che new DateTime(new Date())equivale a scrivere semplicemente new DateTime().
Jonik,

Il metodo millisOfSecondaccede a un oggetto e l'ulteriore chiamata per getestrarre una primitiva intda quell'oggetto. È possibile comprimere le due chiamate utilizzando il metodo getter convenienza, getMillisOfSecond. Joda-Time segue questo schema per molte delle sue proprietà.
Basil Bourque,

1
Cordiali saluti, il progetto Joda-Time è ora in modalità manutenzione , con il team che consiglia la migrazione alle classi java.time .
Basil Bourque,

0

In Java 8 puoi semplicemente farlo

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

ritorna: il numero di millisecondi dall'epoca del 1970-01-01T00: 00: 00Z


1
[A] Questo non è ciò che la domanda ha richiesto. Dice espressamente che non vogliono un conteggio di millisecondi dalla data di riferimento dell'epoca. [B] Potresti accorciarlo facendo cadere ZonedDateTime:Instant.now().toEpochMilli()
Basil Bourque,

0

Ho fatto il test usando Java 8 Non importa l'ordine in cui il costruttore impiega sempre 0 millisecondi e il concat tra 26 e 33 millisecondi sotto e iterazione di 1000 concatenazioni

Spero che ti aiuti a provarlo con il tuo 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));
    }

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

1
Non funziona in alcuni fusi orari. In alcune zone, in alcune date, la giornata potrebbe non iniziare alle 00:00:00. E il giorno potrebbe non durare 24 ore, potrebbe aggiungere o saltare alcune ore o minuti. La LocalDateTimeclasse non può rappresentare un momento, privo di qualsiasi concetto di fuso orario o offset da UTC, e quindi non può tenere traccia di questi problemi di fuso orario.
Basil Bourque,

0

È possibile utilizzare la classe java.util.Calendar per ottenere il tempo in millisecondi. Esempio:

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));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.