Comment convertir currentTimeMillis en une date en Java?


140

J'ai des millisecondes dans certains fichiers journaux générés sur le serveur, je connais également les paramètres régionaux à partir desquels le fichier journal a été généré, mon problème est de convertir les millisecondes en date dans le format spécifié. Le traitement de ce journal se déroule sur un serveur situé dans un fuseau horaire différent. Lors de la conversion au programme "SimpleDateFormat", la date de la machine est prise en compte car une telle date formatée ne représente pas l'heure correcte du serveur. Y a-t-il un moyen de gérer cela avec élégance?

long yourmilliseconds = 1322018752992l;
        //1322018752992-Nov 22, 2011 9:25:52 PM 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS",Locale.US);

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(yourmilliseconds);

System.out.println("GregorianCalendar -"+sdf.format(calendar.getTime()));

DateTime jodaTime = new DateTime(yourmilliseconds, 
                    DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");

System.out.println("jodaTime "+parser1.print(jodaTime));

Production:

Gregorian Calendar -2011-11-23 08:55:52,992
jodaTime 2011-11-22 21:25:52,992

Ne confondez pas les paramètres régionaux avec le fuseau horaire. Totalement séparé. Les paramètres régionaux déterminent la langue humaine pour le nom des mois et des jours, et les normes culturelles telles que l'ordre des parties comme le mois, le jour, etc. Un fuseau horaire est le décalage par rapport à UTC plus les règles de gestion des anomalies telles que l'heure d'été.
Basil Bourque

Le problème était-il que le nombre de millisecondes était un décompte non pas de 1970-01-01T00: 00: 00Z, mais d'un autre moment?
Basil Bourque

Pour votre information, les deux classes date de temps terribles anciens ( GregorianCalendar, SimpleDateFormat, etc.) et l'excellente bibliothèque Joda-Time sont désormais supplantés par les modernes java.time classes.
Basil Bourque

Réponses:


115
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);

J'ai dû définir le calendrier comme final pour le faire fonctionner. final Calendar calendar = Calendar.getInstance();
Victor Augusto

4
Les objets de calendrier sont généralement considérés comme assez volumineux, ils doivent donc être évités lorsque cela est possible. Un objet Date sera préférable en supposant qu'il dispose des fonctionnalités dont vous avez besoin. "Date date = nouvelle date (millisecondes);" fourni dans l'autre réponse par l'utilisateur AVD va être le meilleur itinéraire :)
Dick Lucas

1
En quelque sorte, pour 1515436200000l, je deviens calendar.get(Calendar.MONTH))comme 0!
Sajib Acharya le

Pour info, les anciennes classes de date-heure terriblement 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 .
Basil Bourque

2
@SajibAcharya Notez que les instances de Calendar.MONTH commencent à 0; vous devez en ajouter un pour obtenir le "vrai" mois tel que nous le connaissons. Exemple: 0 = janvier, 1 = février, 2 = mars, etc.
shagberg

256

Vous pouvez utiliser la java.util.Dateclasse et ensuite utiliser SimpleDateFormatpour formater le fichier Date.

Date date=new Date(millis);

Nous pouvons utiliser le package java.time (tutoriel) - API DateTime introduites dans Java SE 8.

var instance = java.time.Instant.ofEpochMilli(millis);
var localDateTime = java.time.LocalDateTime
                        .ofInstant(instance, java.time.ZoneId.of("Asia/Kolkata"));
var zonedDateTime = java.time.ZonedDateTime
                            .ofInstant(instance,java.time.ZoneId.of("Asia/Kolkata"));

// Format the date

var formatter = java.time.format.DateTimeFormatter.ofPattern("u-M-d hh:mm:ss a O");
var string = zonedDateTime.format(formatter);

2
Beaucoup plus efficace.
Chad Bingham

2
Nan. Toutes les méthodes de ne java.util.Datesont pas amorties. (Il y a des API de date et d'heure améliorées dans JDK8 java.time)
adatapost

1
@RafaelZeffa, le constructeur '' 'Date (date longue)' '' n'est pas obsolète
Gugelhupf

L'objet Date est fourni à des fins de compatibilité descendante. Mieux vaut utiliser le calendrier comme suggéré ci-dessus.
Ton Snoei

2
Pour info, les anciennes classes de date-heure terriblement 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 .
Basil Bourque

24

tl; dr

Instant.ofEpochMilli( 1_322_018_752_992L )     // Parse count of milliseconds-since-start-of-1970-UTC into an `Instant`.
       .atZone( ZoneId.of( "Africa/Tunis" ) )  // Assign a time zone to the `Instant` to produce a `ZonedDateTime` object.

Détails

Les autres réponses utilisent des classes obsolètes ou incorrectes.

Évitez les anciennes classes date-heure telles que java.util.Date/.Calendar. Ils se sont avérés mal conçus, déroutants et gênants.

java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Une grande partie des fonctionnalités est rétroportée vers Java 6 et 7 et adaptée à Android . Fabriqué par les mêmes personnes que Joda-Time .

An Instantest un moment sur la chronologie en UTC avec une résolution de nanosecondes . Son époque est le premier moment de 1970 en UTC.

En supposant que vos données d'entrée sont un nombre de millisecondes de 1970-01-01T00: 00: 00Z (pas clair dans la question), alors nous pouvons facilement instancier un fichier Instant.

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

instant.toString (): 2011-11-23T03: 25: 52.992Z

La chaîne au format ISO 8601Z dans cette norme est l'abréviation de et signifie UTCZulu .

Appliquez un fuseau horaire en utilisant un nom de fuseau horaire approprié pour obtenir un fichier ZonedDateTime.

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( zoneId );

Voir ce code exécuté en direct sur IdeOne.com .

Asia/Kolkata fuseau horaire ?

Je suppose que vous avez un fuseau horaire en Inde affectant votre code. Nous voyons ici que l'ajustement au Asia/Kolkatafuseau horaire restitue la même heure de la journée que celle que vous signalez, 08:55soit cinq heures et demie d'avance sur notre valeur UTC 03:25.

2011-11-23T08: 55: 52.992 + 05: 30 [Asia / Kolkata]

Zone par défaut

Vous pouvez appliquer le fuseau horaire par défaut actuel de la JVM. Attention, la valeur par défaut peut changer à tout moment pendant l'exécution . Tout code dans n'importe quel thread de n'importe quelle application dans la JVM peut changer la valeur par défaut actuelle. Si important, demandez à l'utilisateur le fuseau horaire souhaité / attendu.

ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

À propos de java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date, Calendar, et SimpleDateFormat.

Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .

Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Avec un pilote JDBC conforme à JDBC 4.2 ou supérieur, vous pouvez échanger des objets java.time directement avec votre base de données. Pas besoin de chaînes ou de classes java.sql. *.

Où obtenir les classes java.time?

  • Java SE 8 , Java SE 9 et versions ultérieures
    • Intégré.
    • Partie de l'API Java standard avec une implémentation groupée.
    • Java 9 ajoute quelques fonctionnalités et corrections mineures.
  • Java SE 6 et Java SE 7
    • Une grande partie de la fonctionnalité java.time est rétroportée vers Java 6 et 7 dans ThreeTen-Backport .
  • Android

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels futurs ajouts à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval, YearWeek, YearQuarteret plus .


Serait-il facile de convertir l'Instant que vous recommandez ci-dessus au fuseau horaire local qui est la valeur par défaut sur un appareil (par exemple, un smartphone)?
AJW

1
@AJW Oui. Appelez ZoneId.systemDefault(). Voir la nouvelle section ajoutée à la fin de ma réponse.
Basil Bourque

Excellent, je vais essayer.
AJW

14

Le moyen le plus simple de le faire est d'utiliser la classe Joda DateTime et de spécifier à la fois l'horodatage en millisecondes et la DateTimeZone souhaitée.

Je recommande vivement d'éviter les classes Java Date et Calendar intégrées; ils sont terribles.


GorgianCalender n'a pas fonctionné ... pour une raison quelconque, il a pris le fuseau horaire par défaut du système. Joda a parfaitement fonctionné.
Amit

Faites-moi savoir en regardant l'exemple de code si nous pouvons faire quelque chose de différent avec Gregorian
Amit

1
Pour info, le projet Joda-Time est maintenant en mode maintenance , conseillant la migration vers les classes java.time . Voir le didacticiel d'Oracle .
Basil Bourque

13

Si la valeur en millis est le nombre de millis depuis le 1er janvier 1970 GMT, comme c'est le cas pour la JVM, cela est indépendant du fuseau horaire. Si vous souhaitez le formater avec un fuseau horaire spécifique, vous pouvez simplement le convertir en objet GregorianCalendar et définir le fuseau horaire. Après cela, il existe de nombreuses façons de le formater.


1
Ceci est l'exemple de code avec GregorianCalendar et Joda, j'obtiens une sortie correcte avec Joda mais pas avec Gregorian GregorianCalendar calendar = new GregorianCalendar (TimeZone.getTimeZone ("US / Central")); calendar.setTimeInMillis (vos millisecondes); DateTime jodaTime = new DateTime (yourmilliseconds, DateTimeZone.forTimeZone (TimeZone.getTimeZone ("US / Central"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern ("aaaa-MM-jj HH: mm: ss, SSS");
Amit

La définition du fuseau horaire dans l'objet de calendrier ne fonctionnait pas, mais la définition dans l'objet de formatage de date fonctionnait-elle?
Projet de loi du

Qu'est-ce que DateTime et DateTimeFormatter ??
SweetWisher ツ

11

Ma solution

public class CalendarUtils {

    public static String dateFormat = "dd-MM-yyyy hh:mm";
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

    public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(Long.parseLong(milliSeconds));
        return simpleDateFormat.format(calendar.getTime());
    }
}

6

Je fais ça comme ça:

static String formatDate(long dateInMillis) {
    Date date = new Date(dateInMillis);
    return DateFormat.getDateInstance().format(date);
}

Vous pouvez également utiliser getDateInstance(int style)avec les paramètres suivants:

DateFormat.SHORT

DateFormat.MEDIUM

DateFormat.LONG

DateFormat.FULL

DateFormat.DEFAULT



5

Moyen le plus simple:

private String millisToDate(long millis){

    return DateFormat.getDateInstance(DateFormat.SHORT).format(millis);
    //You can use DateFormat.LONG instead of SHORT

}

2

Voici ma solution pour obtenir la date du millisecondes au format de date. Vous devez utiliser la bibliothèque Joda pour exécuter ce code.

import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class time {

    public static void main(String args[]){

        String str = "1431601084000";
        long geTime= Long.parseLong(str);
        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
        calendar.setTimeInMillis(geTime);
        DateTime jodaTime = new DateTime(geTime, 
               DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
        DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd");
        System.out.println("Get Time : "+parser1.print(jodaTime));

   }
}

1

Vous pouvez essayer java.time api;

        Instant date = Instant.ofEpochMilli(1549362600000l);
        LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.