La conversion de Long à Date en Java renvoie 1970


J'ai une liste avec des valeurs longues (par exemple: 1220227200, 1220832000, 1221436800...) que j'ai téléchargé à partir du service Web. Je dois le convertir en Dates. Malheureusement de cette façon, par exemple:

Date d = new Date(1220227200);

Retourne le 1er janvier 1970. Quelqu'un connaît une autre façon de le convertir correctement?

Author: BalusC, 2011-09-20

11 answers

Le Date constructeur (cliquez sur le lien!) accepte le temps comme longen millisecondes, pas en secondes. Vous devez le multiplier par 1000 et vous assurer de le fournir sous la forme long.

Date d = new Date(1220227200L * 1000);

Cela montre ici

Dim 31 août 20: 00: 00 GMT-04: 00 2008

 168
Author: BalusC, 2013-05-24 19:55:20

Tl; dr

java.time.Instant                    // Represent a moment as seen in UTC. Internally, a count of nanoseconds since 1970-01-01T00:00Z.
.ofEpochSecond( 1_220_227_200L )     // Pass a count of whole seconds since the same epoch reference of 1970-01-01T00:00Z.

Connaître vos données

Les gens utilisent diverses précisions dans le suivi du temps en tant que nombre depuis une époque . Ainsi, lorsque vous obtenez des nombres à interpréter comme un nombre depuis une époque, vous devez déterminer:

  • Quelle époque?
    De nombreuses dates d'époques ont été utilisées dans divers systèmes. On utilise courammentPOSIX/Unix time , où l'époque est le premier moment de 1970 en UTC. Mais vous ne devriez passupposer ceci époque.
  • Quelle précision?
    Sommes-nous parler secondes, millisecondes, microsecondes, ou nanosecondes depuis l'époque?
  • Quel fuseau horaire?
    Habituellement, un compte puisque l'époque est dans le fuseau horaire UTC /GMT, c'est-à-dire qu'il n'a aucun décalage de fuseau horaire. Mais parfois, en impliquant des programmeurs inexpérimentés ou ignorants date-heure, il peut y avoir un fuseau horaire implicite.

Dans votre cas, comme d'autres l'ont noté, vous semblez avoir reçu des secondes depuis l'époque Unix. Mais vous passez ces secondes à un constructeur qui attend des millisecondes. La solution consiste donc à multiplier par 1 000.

Leçons apprises:

  • Déterminez, ne supposez pas, la signification des données reçues.
  • Lire le doc .

Graphique montrant diverses granularités de résolution dans les systèmes date-heure, y compris des secondes entières, des millisecondes, des microsecondes et des nanosecondes.

Vos données

Vos données semblent être en secondes entières. Si nous supposons une époque du début de 1970, et si nous supposons le fuseau horaire UTC, alors 1,220,227,200 est le premier moment du premier jour de septembre 2008.

Joda-Temps

Le java.util.La Date et l' .Les classes de calendrier fournies avec Java sont notoirement gênantes. Les éviter. Utilisez plutôt la bibliothèqueJoda-Time ou le nouveau java.time package fourni en Java 8 (et inspiré par Joda-Time).

Notez que, contrairement aux j.u.Date, un DateTime dans Joda-Time connaît vraiment son propre fuseau horaire. Donc, dans l'exemple Joda-Time 2.4 code vu ci-dessous, notez que nous analysons d'abord les millisecondes en utilisant l'hypothèse par défaut d'UTC. Ensuite, deuxièmement, nous attribuons un fuseau horaire de Paris à ajuster. Même moment, dans la chronologie de l'Univers, mais différent horloge murale. Pour la démonstration, nous ajustons à nouveau, à UTC. Presque toujours préférable de spécifier explicitement votre fuseau horaire souhaité/attendu plutôt que de compter sur un défaut implicite (souvent la cause de problèmes dans le travail date-heure).

Nous avons besoin de millisecondes pour construire un DateTime. Alors prenez votre entrée de secondes, et multipliez par mille. Notez que le résultat doit être un long de 64 bits car nous déborderions un int de 32 bits.

long input = 1_220_227_200L;  // Note the "L" appended to long integer literals.
long milliseconds = ( input * 1_000L ); // Use a "long", not the usual "int". Note the appended "L".

Envoie ce nombre de millisecondes au constructeur. Ce constructeur particulier suppose que le nombre est de l'époque Unix de 1970. Ajustez donc le fuseau horaire comme vous le souhaitez, après la construction.

Utilisez des noms de fuseau horaire appropriés , une combinaison de continent et de ville/région. N'utilisez jamais de codes à 3 ou 4 lettres tels que EST car ils sont ni standardisés pas unique.

DateTime dateTimeParis = new DateTime( milliseconds ).withZone( DateTimeZone.forID( "Europe/Paris" ) );

Pour la démonstration, ajustez à nouveau le fuseau horaire.

DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC );
DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) );

Vidage sur console. Notez que la date est différente à Montréal, car la nouvelle journée a commencé en Europe mais pas encore en Amérique.

System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeUTC: " + dateTimeUtc );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );

Lors de l'exécution.

dateTimeParis: 2008-09-01T02:00:00.000+02:00
dateTimeUTC: 2008-09-01T00:00:00.000Z
dateTimeMontréal: 2008-08-31T20:00:00.000-04:00

Java.temps

Les créateurs de Joda-Time nous ont demandé de migrer vers son remplaçant, le java.time framework dès que cela est pratique. Alors que Joda-Time continue d'être activement soutenu, tous le développement futur se fera sur java.classes de temps et leurs extensions dans le projet ThreeTen-Extra.

Le framework java-time est défini par JSR 310 et intégré dans Java 8 et versions ultérieures. Java.les classes de temps ont été rétroportées vers Java 6 et 7 sur le projet ThreeTen-Backport et vers Android dans le projet ThreeTenABP .

Un Instant est un moment dans le scénario de UTC, avec une résolution de nanosecondes. Son epoch est le premier moment de 1970 en UTC.

Instant instant = Instant.ofEpochSecond( 1_220_227_200L );

Appliquer un offset-de-UTC ZoneOffset pour obtenir un OffsetDateTime.

, encore Mieux, si connu, appliquer un fuseau horaire ZoneId pour obtenir un ZonedDateTime.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

Tableau de tous les types date-heure en Java, modernes et hérités

 62
Author: Basil Bourque, 2020-07-10 22:24:00

Il semble que vos longs soient des secondes et non des millisecondes. Le constructeur de date prend du temps en millis, donc

Date d = new Date(timeInSeconds * 1000);
 41
Author: Codemwnci, 2011-09-20 15:10:49

Ne définit que l'heure dans mills sur l'objet Calendar

Calendar c = Calendar.getInstance();
c.setTimeInMillis(1385355600000l);
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH));
System.out.println(c.get(Calendar.DAY_OF_MONTH));
// get Date
System.out.println(c.getTime());
 10
Author: Marlon, 2013-12-17 22:15:21

Ce sont probablement des horodatages en secondeset non en millisecondes ce qui est requis pour le constructeur java new Date(long). Il suffit de les multiplier par 1000 et vous devriez être tout droit.

 9
Author: Magnus Winter, 2011-09-20 15:11:16

Les valeurs longues, très probablement, correspondent à Epoch horodatages, et les valeurs sont:

1220227200 = Lun, 01 Sep 2008 00: 00: 00 GMT

1220832000 = Lun, 08 Sep 2008 00: 00: 00 GMT

1221436800 = Lun, 15 Sep 2008 00: 00: 00 GMT

On peut convertir ces valeurs longues en java.util.Date, en tenant compte du fait java.util.Date utilise millisecs-comme précédemment laissé entendre, mais avec un défaut-comme ceci:

// note: enforcing long literals (L), without it the values would just be wrong.
Date date = new Date(1220227200L * 1000L); 

Maintenant, pour afficher la date correctement, on peut utiliser java.texte.DateFormat comme illustré ci-après:

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("Wrong date time value: " + date);
System.out.println("Correct date time value: " + df.format(date));

Voici les résultats de l'affichage de la valeur longue convertie en java.util.Date sans utilisation et utilisation du DateFormat:

Date wrong (off by 2 hours): Mon Sep 01 02:00:00 CEST 2008
Correct date : Monday, 1 September 2008 00:00:00 o'clock UTC
 5
Author: Jack G., 2013-12-17 22:13:16

Essayez ceci:

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1220227200 * 1000);
System.out.println(cal.getTime());
 4
Author: Mohammad Namvar, 2013-05-24 23:09:36

Essayez ceci en ajustant le format de date.

long longtime = 1212580300;
SimpleDateFormat dateFormat = new SimpleDateFormat("MMddyyHHmm");
Date date = (Date) dateFormat.parseObject(longtime + "");
System.out.println(date);

Remarque: Vérifiez 24 heures ou 12 heures de cycle.

 3
Author: abhimanyu, 2018-11-02 09:27:08

1220227200 correspond au 15 janvier 1980 (et même à une nouvelle date(1220227200).toString () renvoie "Jeu Jan 15 03:57:07 CET 1970"). Si vous passez une valeur longue à une date, c'est-à-dire avant le 01/01/1970, elle renverra en fait une date du 01/01/1970. Assurez-vous que vos valeurs ne sont pas dans cette situation (inférieure à 82800000).

 2
Author: Shivan Dragon, 2011-09-20 15:14:07

New Date(number) renvoie une date qui est number millisecondes après le 1er janvier 1970. Les chances sont que le format de la date n'affiche pas les heures, les minutes et les secondes pour que vous puissiez voir que c'est juste un peu après le 1er janvier 1970.

Vous devez analyser la date en fonction du routage d'analyse correct. Je ne sais pas ce qu'est un 1220227200, mais si c'est quelques secondes après le 1er janvier 1970, multipliez-le pour donner des millisecondes. Si ce n'est pas le cas, convertissez - le d'une manière ou d'une autre en millisecondes après 1970 (si vous le souhaitez continuez à utiliser java.util.Date).

 0
Author: Edwin Buck, 2011-09-20 15:13:27

Fonctionne pour moi. Vous voulez probablement le multiplz avec 1000, car ce que vous obtenez sont les secondes de 1970 et vous devez passer les millisecondes à partir du 1er janvier 1970

 0
Author: leifg, 2011-09-20 15:13:52