Wie kann ich die Anzahl der Millisekunden seit Mitternacht für den aktuellen Wert ermitteln?


124

Beachten Sie, ich möchte nicht Millis aus der Epoche. Ich möchte die Anzahl der Millisekunden, die derzeit auf der Uhr sind.

So habe ich zum Beispiel dieses Stück Code.

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

Gibt es eine Möglichkeit, Millisekunden mit Datum zu erhalten? Gibt es einen anderen Weg, dies zu tun?

Hinweis: System.currentTimeMillis() Gibt mir Millis aus der Epoche, was nicht das ist, wonach ich suche.


2
Du meinst "Millisekunden in der Sekunde", also liegt der Wert immer im Intervall [0, 999], richtig? @thinksteep las den letzten Satz.
Matt Ball

@Lemonio Wenn Sie ein Beispiel geben, wird Ihre Frage klarer.
Basil Bourque

Zu Ihrer Information , die problematischen alten Datums- / Uhrzeitklassen, wie sie java.util.Datejetzt Legacy sind , werden durch die Klassen java.time ersetzt .
Basil Bourque

Zu Ihrer Information , die problematischen alten Datums- / Uhrzeitklassen, wie sie java.util.Datejetzt Legacy sind , werden durch die Klassen java.time ersetzt . Siehe Tutorial von Oracle .
Basil Bourque

1
@ChrisNeve JEP 150 , von Brian Goetz gebilligt , JSR 310 wurde einstimmig angenommen , ein von Oracle veröffentlichter technischer Artikel , und das alte Oracle-Tutorial mit Datum und Uhrzeit wurde durch ein neues java.time-Tutorial ersetzt .
Basil Bourque

Antworten:


197

Meinst du?

long millis = System.currentTimeMillis() % 1000;

BTW Windows erlaubt keine Zeitreise bis 1969

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

8
Beachten Sie, dass wenn Sie in der Zeit vor der Unix-Epoche zurückreisen, dies einen negativen Wert ergibt, während die Verwendung dies c.get(Calendar.MILLISECOND)nicht tun sollte. Denken Sie immer an die Eckkoffer!
Jon Skeet

und wenn jemand eine Zeitzone definiert, die nicht an der zweiten Grenze liegt, oder eine Schaltmillisekunde hinzufügt, bricht dies. =))
Markus Mikkolainen

35
Java unterstützt keine Zeitreisen.
R. Martinho Fernandes

1
@ MarkusMikkolainen: Nein, System.currentTimeMillis()wird nicht von Zeitzonen beeinflusst.
Jon Skeet

1
@ PeterLawrey: Nun, es könnte oder es könnte nicht. Es liegt an der Umsetzung. Aus den Dokumenten für Datum: "Eine Sekunde wird durch eine Ganzzahl von 0 bis 61 dargestellt; die Werte 60 und 61 treten nur für Schaltsekunden und selbst dann nur in Java-Implementierungen auf, die Schaltsekunden tatsächlich korrekt verfolgen. Aufgrund der Art und Weise, in der der Sprung erfolgt Sekunden werden derzeit eingeführt. Es ist äußerst unwahrscheinlich, dass zwei Schaltsekunden in derselben Minute auftreten. Diese Spezifikation folgt jedoch den Datums- und Zeitkonventionen für ISO C. "
Jon Skeet

24

Kalender verwenden

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

oder

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

In der Praxis denke ich jedoch, dass es fast immer gleich System.currentTimeMillis ()% 1000 sein wird; es sei denn, jemand hat Schaltmillisekunden oder ein Kalender ist mit einer Epoche definiert, die nicht an einer zweiten Grenze liegt.


Der Kalender ist standardmäßig bereits die aktuelle Zeit, und bei MILLISECOND gibt es keine s.
kgautron


13

tl; dr

Sie fragen nach dem Bruchteil einer Sekunde der aktuellen Zeit als Anzahl von Millisekunden ( nicht ab Epoche gezählt).

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

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

  1. Erhalten Sie den Bruchteil einer Sekunde in Nanosekunden (Milliarden).
  2. Teilen Sie durch Tausend, um auf Millisekunden (Tausend) zu kürzen.

Sehen Sie diesen Code live auf IdeOne.com .

Mit java.time

Der moderne Weg ist mit den java.time Klassen.

Erfassen Sie den aktuellen Moment in UTC.

Instant.now()

Verwenden Sie die Instant.getMethode, um den Wert von a abzufragen TemporalField. In unserem Fall ist das, was TemporalFieldwir wollen ChronoField.MILLI_OF_SECOND.

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

Oder rechnen Sie selbst.

Wahrscheinlicher ist, dass Sie dies nach einer bestimmten Zeitzone fragen. Der Bruchteil einer Sekunde ist wahrscheinlich der gleiche wie bei, Instantaber es gibt so viele Anomalien mit Zeitzonen, dass ich zögere, diese Annahme zu treffen.

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

Fragen Sie für den Bruchteil einer Sekunde ab. Die Frage wurde nach Millisekunden gestellt , aber Java.time-Klassen verwenden eine feinere Auflösung von Nanosekunden . Das bedeutet, dass die Anzahl der Nanosekunden zwischen 0 und 999.999.999 liegt.

long nanosFractionOfSecond = zdt.getNano();

Wenn Sie wirklich Millisekunden wollen, schneiden Sie die feineren Daten durch Teilen durch eine Million ab. Eine halbe Sekunde beträgt beispielsweise 500.000.000 Nanosekunden und 500 Millisekunden.

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

Über java.time

Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Woher bekomme ich die java.time-Klassen?

Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden Interval, YearWeek, YearQuarter, und mehr .


12

Ich habe oben einige ausprobiert, aber sie scheinen @ 1000 zurückzusetzen

Dieser funktioniert definitiv und sollte auch das Jahr berücksichtigen

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

und machen Sie dasselbe bei Bedarf für die Endzeit.


1
Beantwortung der falschen Frage. Das sind aktuelle Millis aus der Epoche, nicht der Millis-Teil der aktuellen Zeit.
Sean Van Gorder

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

Fri Apr 04 14:27:05 PDT 2014


2

Joda-Zeit

Ich denke, Sie können Joda-Time verwenden , um dies zu tun. Schauen Sie sich die DateTimeKlasse und ihre getMillisOfSecondMethode an. Etwas wie

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

Kompilierungsfehler: " getMillis()hat geschützten Zugriff"; müssen get()stattdessen verwenden. Beachten Sie auch, dass new DateTime(new Date())dies dem einfachen Schreiben entspricht new DateTime().
Jonik

Die Methode millisOfSecondgreift auf ein Objekt zu und der weitere Aufruf zum getExtrahieren eines Grundelements intaus diesem Objekt. Sie können die beiden Aufrufe mit der Convenience-Getter-Methode reduzieren getMillisOfSecond. Joda-Time folgt diesem Muster für viele seiner Eigenschaften.
Basil Bourque

1
Zu Ihrer Information , das Joda-Time- Projekt befindet sich jetzt im Wartungsmodus. Das Team empfiehlt die Migration zu den Klassen java.time .
Basil Bourque

0

In Java 8 können Sie dies einfach tun

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

Rückgabe: Die Anzahl der Millisekunden seit der Epoche 1970-01-01T00: 00: 00Z


1
[A] Dies ist nicht das, worum es in der Frage ging. Sagt ausdrücklich, dass sie seit dem Epochenreferenzdatum keine Millisekunden mehr wollen. [B] Sie könnten das verkürzen, indem Sie die ZonedDateTime fallen lassen:Instant.now().toEpochMilli()
Basil Bourque

0

Ich habe den Test mit Java 8 durchgeführt. Es spielt keine Rolle, in welcher Reihenfolge der Builder immer 0 Millisekunden und die Konat zwischen 26 und 33 Millisekunden unter und Iteration einer 1000-Verkettung benötigt

Hoffe, es hilft, es mit Ihrer Idee zu versuchen

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
Funktioniert in einigen Zeitzonen nicht. In einigen Zonen beginnt der Tag an bestimmten Daten möglicherweise nicht um 00:00:00 Uhr. Und der Tag ist möglicherweise nicht 24 Stunden lang, kann einige Stunden oder Minuten hinzufügen oder überspringen. Die LocalDateTimeKlasse kann keinen Moment darstellen, da kein Konzept für Zeitzone oder Versatz von UTC vorliegt, und kann daher diese Zeitzonenprobleme nicht verfolgen.
Basil Bourque

0

Sie können die Klasse java.util.Calendar verwenden, um die Zeit in Millisekunden abzurufen. Beispiel:

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));
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.