Konvertieren Sie den Zeitstempel in Millisekunden in eine Zeichenfolgenformatierte Zeit in Java

125

Ich versuche, einen langen Wert ( Anzahl der Millisekunden, die seit dem 1.1.1970, dh der Epoche, vergangen sind ) in die Formatzeit umzuwandeln h:m:s:ms.

Den langen Wert, den ich als Zeitstempel verwende, erhalte ich aus dem Feld timestampeines Protokollierungsereignisses von log4j.

Bisher habe ich Folgendes versucht und es schlägt fehl:

logEvent.timeStamp/ (1000*60*60)
TimeUnit.MILLISECONDS.toMinutes(logEvent.timeStamp)

aber ich bekomme einen falschen Wert:

1289375173771 for logEvent.timeStamp
358159  for logEvent.timeStamp/ (1000*60*60) 
21489586 for TimeUnit.MILLISECONDS.toMinutes(logEvent.timeStamp)

Wie gehe ich vor?

Cratylus
quelle

Antworten:

187

Versuche dies:

Date date = new Date(logEvent.timeSTamp);
DateFormat formatter = new SimpleDateFormat("HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateFormatted = formatter.format(date);

Unter SimpleDateFormat finden Sie eine Beschreibung anderer Formatzeichenfolgen , die von der Klasse akzeptiert werden.

Siehe ausführbares Beispiel mit einer Eingabe von 1200 ms.

Manolowar
quelle
8
Kommentar: HH druckt die Stunde zu diesem Zeitpunkt (0-23), nicht die Gesamtstundenzahl, die seit 1970 vergangen ist. Sagen Sie einfach.
JohnyTex
4
Und vergiss nicht. Altes SimpleDateFormat kann nicht mit mehreren Threads verwendet werden.
Keiki
zu importieren SimpleDateFormat, verwenden Sie den Import wie folgt:import java.text.*;
Naveen Kumar RB
1
Zu Ihrer Information, die störenden alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle . Siehe: stackoverflow.com/a/4142428/642706
Basil Bourque
1
Was ist die Art von Logevent? Können Sie bitte die Frage stellen?
Raulp
127
long millis = durationInMillis % 1000;
long second = (durationInMillis / 1000) % 60;
long minute = (durationInMillis / (1000 * 60)) % 60;
long hour = (durationInMillis / (1000 * 60 * 60)) % 24;

String time = String.format("%02d:%02d:%02d.%d", hour, minute, second, millis);
Brajendra Pandey
quelle
13
Ich mag Ihre Lösung besser als die akzeptierte Antwort, da sie etwas expliziter ist und keine Probleme mit dem Gebietsschema hat. Sie verpassen jedoch den letzten Teil: millis = millis% 1000, wodurch zu Recht Millisekunden am Ende der formatierten Zeichenfolge stehen.
Ondrej Burkert
7
@WesleyDeKeirsmaeker Im Allgemeinen ist Lesbarkeit wichtiger als Prägnanz.
Alphaaa
2
Warum mit 24 für Stunden Rest?
Baboo
2
Division ist nicht assoziativ: 50000 / (1000 * 60) = 0,8333333333, während 50000/1000 * 60 = 3000.
Farnett
3
'millis = millis% 1000' fehlt: D \ n und wenn Sie Tage brauchen, können Sie loslegen: 'lange Tage = (millis / (1000 * 60 * 60 * 24));'
Adreamus
38

Ich zeige Ihnen drei Möglichkeiten, um (a) das Minutenfeld aus einem langen Wert zu erhalten und (b) es mit dem gewünschten Datumsformat zu drucken. Man verwendet java.util.Calendar , ein anderer verwendet Joda-Time und der letzte das in Java 8 und höher integrierte java.time-Framework.

Das java.time-Framework ersetzt die alten gebündelten Datums- und Uhrzeitklassen und ist von Joda-Time inspiriert, definiert durch JSR 310 und erweitert durch das ThreeTen-Extra-Projekt.

Das java.time-Framework ist der richtige Weg, wenn Sie Java 8 und höher verwenden. Verwenden Sie andernfalls wie Android Joda-Time. Die Klassen java.util.Date/.Calendar sind notorisch problematisch und sollten vermieden werden.

java.util.Date & .Calendar

final long timestamp = new Date().getTime();

// with java.util.Date/Calendar api
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timestamp);
// here's how to get the minutes
final int minutes = cal.get(Calendar.MINUTE);
// and here's how to get the String representation
final String timeString =
    new SimpleDateFormat("HH:mm:ss:SSS").format(cal.getTime());
System.out.println(minutes);
System.out.println(timeString);

Joda-Zeit

// with JodaTime 2.4
final DateTime dt = new DateTime(timestamp);
// here's how to get the minutes
final int minutes2 = dt.getMinuteOfHour();
// and here's how to get the String representation
final String timeString2 = dt.toString("HH:mm:ss:SSS");
System.out.println(minutes2);
System.out.println(timeString2);

Ausgabe:

24
09: 24: 10: 254
24
09: 24: 10: 254

java.time

long millisecondsSinceEpoch = 1289375173771L;
Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , ZoneOffset.UTC );

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "HH:mm:ss:SSS" );
String output = formatter.format ( zdt );

System.out.println ( "millisecondsSinceEpoch: " + millisecondsSinceEpoch + " instant: " + instant + " output: " + output );

MillisekundenSeitEpoch: 1289375173771 Instant: 2010-11-10T07: 46: 13.771Z Ausgabe: 07: 46: 13: 771

Sean Patrick Floyd
quelle
1
Gibt es einen Leistungsgrund oder einen anderen Grund, warum ich Joda dem Kalender vorziehen sollte?
Cratylus
1
in einfachen Fällen wie diesen, nein. Im Allgemeinen: Jodas API ist besser gestaltet. zB Java Dates sind veränderbar Joda DateTimes nicht. Joda ist auch programmiererfreundlicher. Sie können auf fast alle Funktionen der DateTime-Klasse zugreifen, ohne zwischen Datum und Kalender hin und her konvertieren zu müssen
Sean Patrick Floyd
Hat es irgendwelche Abhängigkeiten, die ich beachten sollte?
Cratylus
2
Gute Antwort, aber ich schlage vor, auch die Zeitzone anzugeben, anstatt sich implizit auf die aktuelle Standardzeitzone der JVM zu verlassen. Der Aufruf des Konstruktors von DateTime hätte also ein zweites Argument, ein DateTimeZoneObjekt. So:new DateTime( timestamp, DateTimeZone.forID( "America/Montreal" ) )
Basil Bourque
2
@Cratylus Die Klassen java.time ersetzen sowohl Joda-Time als auch die alten, mit Java gebündelten älteren Date-Time-Klassen. Joda-Time inspirierte die java.time-Klassen, beide Projekte wurden von demselben Mann, Stephen Colbourne, geleitet.
Basil Bourque
22

Es ist möglich, Apache Commons (commons-lang3) und seine DurationFormatUtils-Klasse zu verwenden.

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.1</version>
</dependency>

Beispielsweise:

String formattedDuration = DurationFormatUtils.formatDurationHMS(12313152);
// formattedDuration value is "3:25:13.152"
String otherFormattedDuration = DurationFormatUtils.formatDuration(12313152, DurationFormatUtils.ISO_EXTENDED_FORMAT_PATTERN);
// otherFormattedDuration value is "P0000Y0M0DT3H25M13.152S"

Hoffe es kann helfen ...

YoCha
quelle
8
long second = TimeUnit.MILLISECONDS.toSeconds(millis);
long minute = TimeUnit.MILLISECONDS.toMinutes(millis);
long hour = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.SECONDS.toMillis(second);
return String.format("%02d:%02d:%02d:%d", hour, minute, second, millis);
Lo Ka
quelle
2
Das scheint nicht richtig zu sein. Hat TimeUnit.MILLISECONDS.toSeconds()zum Beispiel convert Millisekunden auf die gleiche Dauer in Sekunden oder die verbleibenden Sekunden nach Stunden und Minuten abgezogen? Die Lösung erfordert letzteres.
Derek Mahar
Diese Methode ist falsch, sie gibt 431220: 25873204: 1552392282: 0 zurück, wenn ich das Datum vom 12. März 2019 um 13h04 42s
0ddlyoko
6
public static String timeDifference(long timeDifference1) {
long timeDifference = timeDifference1/1000;
int h = (int) (timeDifference / (3600));
int m = (int) ((timeDifference - (h * 3600)) / 60);
int s = (int) (timeDifference - (h * 3600) - m * 60);

return String.format("%02d:%02d:%02d", h,m,s);
Vivek Pal
quelle
4

Tun

logEvent.timeStamp / (1000*60*60)

gibt Ihnen Stunden, nicht Minuten. Versuchen:

logEvent.timeStamp / (1000*60)

und Sie werden am Ende die gleiche Antwort erhalten wie

TimeUnit.MILLISECONDS.toMinutes(logEvent.timeStamp)
Nico Huysamen
quelle
Aber TimeUnit.MILLISECONDS.toMinutes (logEvent.timeStamp) gibt auch meinen Müll. 21489586 ist keine Minuten!
Cratylus
1
Dies ist die Anzahl der Minuten, die seit dem 01.01.1970 vergangen sind.
Nico Huysamen
Ok, wie bekomme ich das gewünschte Format? Dh 10: 50: 40: 450? Ich weiß nicht, wie ich die Anzahl der Minuten seit 1970 verwenden soll.
Cratylus
Oh, tut mir leid, ich dachte nur, du wolltest wissen, wie man einen Sinn daraus macht. Siehe den Beitrag von Seanizer, der es abdecken sollte.
Nico Huysamen
3

Versuche dies:

    String sMillis = "10997195233";
    double dMillis = 0;

    int days = 0;
    int hours = 0;
    int minutes = 0;
    int seconds = 0;
    int millis = 0;

    String sTime;

    try {
        dMillis = Double.parseDouble(sMillis);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }


    seconds = (int)(dMillis / 1000) % 60;
    millis = (int)(dMillis % 1000);

    if (seconds > 0) {
        minutes = (int)(dMillis / 1000 / 60) % 60;
        if (minutes > 0) {
            hours = (int)(dMillis / 1000 / 60 / 60) % 24;
            if (hours > 0) {
                days = (int)(dMillis / 1000 / 60 / 60 / 24);
                if (days > 0) {
                    sTime = days + " days " + hours + " hours " + minutes + " min " + seconds + " sec " + millis + " millisec";
                } else {
                    sTime = hours + " hours " + minutes + " min " + seconds + " sec " + millis + " millisec";
                }
            } else {
                sTime = minutes + " min " + seconds + " sec " + millis + " millisec";
            }
        } else {
            sTime = seconds + " sec " + millis + " millisec";
        }
    } else {
        sTime = dMillis + " millisec";
    }

    System.out.println("time: " + sTime);
LeoZao
quelle
0
    long hours = TimeUnit.MILLISECONDS.toHours(timeInMilliseconds);
    long minutes = TimeUnit.MILLISECONDS.toMinutes(timeInMilliseconds - TimeUnit.HOURS.toMillis(hours));
    long seconds = TimeUnit.MILLISECONDS
            .toSeconds(timeInMilliseconds - TimeUnit.HOURS.toMillis(hours) - TimeUnit.MINUTES.toMillis(minutes));
    long milliseconds = timeInMilliseconds - TimeUnit.HOURS.toMillis(hours)
            - TimeUnit.MINUTES.toMillis(minutes) - TimeUnit.SECONDS.toMillis(seconds);
    return String.format("%02d:%02d:%02d:%d", hours, minutes, seconds, milliseconds);
Joel Richard Koett
quelle