web-dev-qa-db-fra.com

Obtenir l’objet Date au format UTC dans Java

J'ai écrit le code suivant. Je souhaite obtenir l'objet Date au format UTC.

Je peux obtenir la chaîne de date attendue en UTC en utilisant SimpleDateFormat. Mais en utilisant le même objet SimpleDateFormat, je ne parviens pas à obtenir un objet au format UTC. Il renvoie un objet au format IST.

Après recherche, j'ai trouvé que l'objet Date ne stockait pas les informations d'horodatage.

Comment obtenir un objet de date au format UTC?

import Java.text.DateFormat;
import Java.text.ParseException;
import Java.text.SimpleDateFormat;
import Java.util.Date;
import Java.util.TimeZone;

public class dddd {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("Input - "+1393572325000L);
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date date= new Date(1393572325000L);  
        String dateString = formatter.format(date);

        System.out.println("Converted UTC TIME (using Format method) : "+dateString);

        Date date2 =null;
        try {
            date2 = formatter.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }


        System.out.println("Parsed Date Object (using Parse method) : "+date2);

        System.out.println("Expected Date Object : Fri Feb 28 07:25:25 UTC 2014");

    }

}

Ceci imprime la sortie suivante:

Input - 1393572325000
Converted UTC TIME (using Format method) : 2014-02-28 07:25:25
Parsed Date Object (using Parse method) : Fri Feb 28 12:55:25 IST 2014
Expected Date Object : Fri Feb 28 07:25:25 UTC 2014
28
Ninad Pingale
final Date currentTime = new Date();
final SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC time: " + sdf.format(currentTime));
40
Dipali Vasani

Une date n'a pas de fuseau horaire. Ce que vous voyez n’est que le formatage de la date par la méthode Date.toString(), qui utilise votre fuseau horaire local, toujours, pour transformer la date indépendante du fuseau horaire en une chaîne que vous pouvez comprendre.

Si vous souhaitez afficher la date sans fuseau horaire sous forme de chaîne utilisant le fuseau horaire UTC, utilisez un SimpleDateFormat avec le fuseau horaire UTC (comme vous l'avez déjà fait dans votre question).

En d'autres termes, le fuseau horaire n'est pas une propriété de la date. C'est une propriété du format utilisé pour transformer la date en chaîne.

23
JB Nizet

tl; dr

Instant.ofEpochMilli ( 1_393_572_325_000L )
       .toString()

2014-02-28T07: 25: 25Z

Détails

(a) Vous semblez ne pas bien comprendre ce qu'est une date. Comme le réponse de JB Nizet a dit, une date indique le nombre de millisecondes écoulées depuis le nixEpoch (premier moment de 1970) dans le - UTC fuseau horaire (c'est-à-dire sans décalage de fuseau horaire). Donc, une date n'a pas de fuseau horaire. Et il n'a pas de "format". Nous créons des représentations de chaîne à partir de une valeur de date, mais la date elle-même n'est pas une chaîne et n'a pas de chaîne .

(b) Vous faites référence à un "format UTC". Le format UTC n'est pas un format, je n'en ai pas entendu parler. TC (Coordinated Universal Time) est le point d'origine des fuseaux horaires. Les fuseaux horaires situés à l'est de l'observatoire royal de Greenwich, à Londres, ont un certain nombre d'heures et de minutes d'avance sur UTC. Les fuseaux horaires ouest sont situés derrière UTC.

Vous semblez faire référence à ISO 8601 chaînes formatées. Vous utilisez le format facultatif, en omettant (1) le T du milieu et (2) le décalage par rapport au temps UTC à la fin. À moins de présenter la chaîne à un utilisateur dans l'interface utilisateur de votre application, je vous suggère généralement de vous en tenir au format habituel:

  • 2014-02-27T23:03:14+05:30
  • 2014-02-27T23:03:14Z _ ('Z' pour Zulu, ou UTC, avec un décalage de +00: 00)

(c) Évitez les codes de fuseau horaire de 3 ou 4 lettres. Ils ne sont ni normalisés ni uniques. "IST", par exemple, peut signifier soit heure standard indienne , soit heure normale irlandaise .

(d) Faites des efforts pour rechercher StackOverflow avant de poster. Vous auriez trouvé toutes vos réponses.

(e) Évitez les classes Java.util.Date & Calendar fournies avec Java. Ils sont notoirement gênants. Utilisez la bibliothèque Joda-Time ou Java 8) (inspiré de Joda-Time, défini par JSR 310).

Java.time

Les classes Java.time utilisent par défaut les formats standard ISO 8601 lors de l'analyse et de la génération de chaînes.

OffsetDateTime odt = OffsetDateTime.parse( "2014-02-27T23:03:14+05:30" ); 
Instant instant = Instant.parse( "2014-02-27T23:03:14Z" );

Analysez votre compte en millisecondes depuis l’époque du premier moment de 1970 en UTC.

Instant instant = Instant.ofEpochMilli ( 1_393_572_325_000L );

instant.toString (): 2014-02-28T07: 25: 25Z

Ajustez ce Instant dans le fuseau horaire souhaité.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

zdt.toString (): 2014-02-28T02: 25: 25-05: 00 [Amérique/Montréal]


À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancien problème - legacy classes date-heure telles que Java.util.Date , Calendar , & SimpleDateFormat .

Le projet Joda-Time , actuellement en mode de maintenance , conseille de migrer vers le Java.time = cours.

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

Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou une version ultérieure. Pas besoin de chaînes, pas besoin de Java.sql.* Des classes.

Où obtenir les classes Java.time?

Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez trouver ici quelques classes utiles telles que Interval , YearWeek , YearQuarter , et plus .


Joda-Time

UPDATE: Le projet Joda-Time , maintenant en mode de maintenance , conseille de migrer vers le - Java.time classes.

Joda-Time utilise ISO 8601 par défaut.

Un objet Joda-Time DateTime connaît son fuseau horaire, contrairement à un objet Java.util.Date.

Il est généralement préférable de spécifier explicitement un fuseau horaire plutôt que de s’appuyer sur le fuseau horaire par défaut.

Exemple de code

long input = 1393572325000L;
DateTime dateTimeUtc = new DateTime( input, DateTimeZone.UTC );

DateTimeZone timeZoneIndia = DateTimeZone.forID( "Asia/Kolkata" );
DateTimeZone timeZoneIreland = DateTimeZone.forID( "Europe/Dublin" );

DateTime dateTimeIndia = dateTimeUtc.withZone( timeZoneIndia );
DateTime dateTimeIreland = dateTimeIndia.withZone( timeZoneIreland );

// Use a formatter to create a String representation. The formatter can adjust time zone if you so desire.
DateTimeFormatter formatter = DateTimeFormat.forStyle( "FM" ).withLocale( Locale.CANADA_FRENCH ).withZone( DateTimeZone.forID( "America/Montreal" ) );
String output = formatter.print( dateTimeIreland );

Décharger pour consoler…

// All three of these date-time objects represent the *same* moment in the timeline of the Universe.
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeIreland: " + dateTimeIreland );

System.out.println( "output for Montréal: " + output );

Quand couru…

dateTimeUtc: 2014-02-28T07:25:25.000Z
dateTimeIndia: 2014-02-28T12:55:25.000+05:30
dateTimeIreland: 2014-02-28T07:25:25.000Z
output for Montréal: vendredi 28 février 2014 02:25:25

 En réalité, Java.util.Date a un fuseau horaire. Ce fuseau horaire est attribué profondément dans son code source. Pourtant, la classe ignore ce fuseau horaire pour des raisons pratiques. Et sa méthode toString applique le fuseau horaire actuel par défaut de la machine virtuelle Java au lieu de ce fuseau horaire interne. Déroutant? Oui. C'est l'une des nombreuses raisons d'éviter les anciennes classes Java.util.Date/.Calendar. Utilisez plutôt Java.time et/ou Joda-Time.

15
Basil Bourque

Dans Java 8, il est très facile d’obtenir un horodatage en UTC en utilisant Java 8 Java.time.Instant bibliothèque:

Instant.now();

Ce petit mot de code renverra l'horodatage UTC.

5
Trilok Singh Devda

Vous pouvez soustraire la différence de fuseau horaire à partir de maintenant.

final Calendar calendar  = Calendar.getInstance();
final int      utcOffset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
final long     tempDate  = new Date().getTime();

return new Date(tempDate - utcOffset);
2
Fırat KÜÇÜK