Convertir l'horodatage en millisecondes en temps au format chaîne en Java

126

J'essaye de convertir une valeur longue ( nombre de millisecondes écoulées du 1/1/1970 ie Epoch ) en temps de format h:m:s:ms.

La valeur longue que j'utilise comme horodatage, j'obtiens du champ timestampd'un événement de journalisation de log4j.

Jusqu'à présent, j'ai essayé ce qui suit et cela échoue:

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

mais j'obtiens une valeur incorrecte:

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

Comment dois-je procéder?

Cratyle
la source

Réponses:

188

Essaye ça:

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

Voir SimpleDateFormat pour une description des autres chaînes de format acceptées par la classe.

Voir l' exemple exécutable en utilisant une entrée de 1200 ms.

Manolowar
la source
8
Commentaire: HH imprimera l'heure à cette date (0-23), pas le nombre total d'heures écoulées depuis 1970. Il suffit de dire.
JohnyTex
4
Et n'oubliez pas. L'ancien SimpleDateFormat ne peut pas être utilisé en multithread.
keiki
pour importer SimpleDateFormat, utilisez l'importation comme suit:import java.text.*;
Naveen Kumar RB
1
Pour info, les anciennes classes de date-heure gênantes telles que java.util.Date, java.util.Calendaret java.text.SimpleDateFormatsont maintenant héritées , supplantées par les classes java.time intégrées à Java 8 et versions ultérieures. Voir le didacticiel d'Oracle . Voir: stackoverflow.com/a/4142428/642706
Basil Bourque
1
quel est le type de logevent? Pouvez-vous s'il vous plaît mettre la question?
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
la source
13
J'aime mieux votre solution que la réponse acceptée car elle est un peu plus explicite et ne souffre pas de problèmes de locale. Bien que vous manquiez la dernière partie: millis = millis% 1000, qui mettrait à juste titre des millisecondes à la fin de la chaîne formatée.
Ondrej Burkert
7
@WesleyDeKeirsmaeker, en général, la lisibilité est plus importante que la concision.
Alphaaa
2
pourquoi rester avec 24 heures?
baboo le
2
La division n'est pas associative: 50000 / (1000 * 60) = 0.8333333333 tandis que 50000/1000 * 60 = 3000.
farnett
3
'millis = millis% 1000' est manquant: D \ n et si vous avez besoin de jours, c'est parti: 'longs jours = (millis / (1000 * 60 * 60 * 24));'
Adreamus
38

Je vais vous montrer trois façons de (a) obtenir le champ des minutes à partir d'une valeur longue et (b) de l'imprimer en utilisant le format de date souhaité. L'un utilise java.util.Calendar , l'autre utilise Joda-Time et le dernier utilise le framework java.time intégré à Java 8 et versions ultérieures.

Le framework java.time supplante les anciennes classes date-heure groupées et s'inspire de Joda-Time, défini par JSR 310 et étendu par le projet ThreeTen-Extra.

Le framework java.time est la voie à suivre lors de l'utilisation de Java 8 et versions ultérieures. Sinon, comme Android, utilisez Joda-Time. Les classes java.util.Date/.Calendar sont notoirement gênantes et doivent être évitées.

java.util.Date et .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-Time

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

Production:

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

millisecondes DepuisEpoch: 1289375173771 instant: 2010-11-10T07: 46: 13.771Z sortie: 07: 46: 13: 771

Sean Patrick Floyd
la source
1
Y a-t-il une raison de performances ou une autre raison, je devrais préférer Joda à Calendar?
Cratylus
1
dans des cas simples comme celui-ci, non. En général: l'API de Joda est mieux conçue. par exemple, les dates java sont mutables Les dates-heures Joda ne le sont pas. Joda est également plus convivial pour les programmeurs, vous pouvez accéder à presque toutes les fonctionnalités de la classe DateTime sans avoir à convertir entre la date et le calendrier
Sean Patrick Floyd
a-t-il des dépendances dont je devrais être conscient?
Cratylus
2
Bonne réponse, mais je suggère également de spécifier le fuseau horaire plutôt que de se fier implicitement au fuseau horaire par défaut actuel de la JVM. Ainsi, l'appel au constructeur de DateTime aurait un deuxième argument, un DateTimeZoneobjet. Comme ça:new DateTime( timestamp, DateTimeZone.forID( "America/Montreal" ) )
Basil Bourque
2
@Cratylus Les classes java.time remplacent à la fois Joda-Time et les anciennes classes date-heure intégrées à Java. Joda-Time a inspiré les classes java.time, les deux projets dirigés par le même homme, Stephen Colbourne.
Basil Bourque
22

Il est possible d'utiliser apache commons (commons-lang3) et sa classe DurationFormatUtils.

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

Par exemple:

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"

J'espère que cela peut aider ...

YoCha
la source
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
la source
2
Cela ne semble pas correct. Par TimeUnit.MILLISECONDS.toSeconds()exemple, convertit-il les millisecondes en la même durée en secondes ou les secondes restantes après avoir soustrait des heures et des minutes? La solution nécessite ce dernier.
Derek Mahar
Cette méthode est incorrecte, elle renvoie 431220: 25873204: 1552392282: 0 si je veux convertir la date du 12 mars 2019 à 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
la source
4

Faire

logEvent.timeStamp / (1000*60*60)

vous donnera des heures, pas des minutes. Essayer:

logEvent.timeStamp / (1000*60)

et vous vous retrouverez avec la même réponse que

TimeUnit.MILLISECONDS.toMinutes(logEvent.timeStamp)
Nico Huysamen
la source
Mais TimeUnit.MILLISECONDS.toMinutes (logEvent.timeStamp) donne aussi mes déchets. 21489586 n'est pas des minutes!
Cratylus
1
C'est le nombre de minutes écoulées depuis le 01/01/1970.
Nico Huysamen
Ok, alors comment obtenir le format que je veux? Ie 10: 50: 40: 450? Je ne sais pas comment utiliser le nombre de minutes depuis 1970.
Cratylus
O désolé, je pensais juste que tu voulais savoir comment en comprendre le sens. Voir le post par seanizer, qui devrait le couvrir.
Nico Huysamen
3

Essaye ça:

    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
la source
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);
Joël Richard Koett
la source