Obtenir la date dans le fuseau horaire actuel en java


Je cherche sur le net depuis quelques heures pour obtenir le datetime dans mon fuseau horaire système.

Lorsque j'utilise le calendrier.getTimezone.getDefaultName il me renvoie toujours GMT. (idéalement, il devrait renvoyer mon fuseau horaire actuel, qui est IST) J'essaie de convertir cette chaîne "2014-02-14T06:04:00:00", qui est en GMT à mon fuseau horaire datetime. Il me renvoie toujours la même heure en GMT.

Tout ce que je vois, c'est que tout le monde suggère d'utiliser Timezone. j'.e,

dateFormatter.setTimezone("any_arbitary_timezone");

Point est-ce que mon application sera utilisée dans différents endroits géographiques. Je ne peux pas le définir sur un fuseau horaire particulier. Il doit être défini sur le fuseau horaire du système, afin qu'il puisse s'afficher dans le fuseau horaire dans lequel l'utilisateur se trouve actuellement

Author: Kiran Kulkarni, 2014-07-17

4 answers

Voici un moyen d'obtenir l'id d'un TimeZone qui correspond au décalage de votre horloge système locale,

Calendar cal = Calendar.getInstance();
long milliDiff = cal.get(Calendar.ZONE_OFFSET);
// Got local offset, now loop through available timezone id(s).
String [] ids = TimeZone.getAvailableIDs();
String name = null;
for (String id : ids) {
  TimeZone tz = TimeZone.getTimeZone(id);
  if (tz.getRawOffset() == milliDiff) {
    // Found a match.
    name = id;
    break;
  }
}
System.out.println(name);
 9
Author: Elliott Frisch, 2014-07-17 14:31:01

Tl; dr

Utilisez le java moderne.temps classes.

ZonedDateTime.now(           // Capture the current moment in the wall-clock time used by the people of a certain region (a time zone).
    ZoneId.systemDefault()   // Get the JVM’s current default time zone. Can change at any moment during runtime. If important, confirm with the user.
)                            // Renders a `ZonedDateTime` object. To see the same moment in UTC, extract a `Instant` object by calling `ZonedDateTime::getInstant`.

Vous pouvez omettre l'appel explicite de ZoneId.systemDefault.

ZonedDateTime.now()          // Capture the current moment in the JVM’s current default time zone.

Analysez votre chaîne comme un LocalDateTime, et ajuster dans le fuseau horaire souhaité.

LocalDateTime.parse( "2014-02-14T06:04:00:00" )    // Parse a string lacking any indicator of time zone or offset-from-UTC. *Not* a specific point on the timeline.
             .atOffset( ZoneOffset.UTC )           // Apply UTC as we are certain that offset-from-UTC of zero was intended by the supplier of that input string. Returns a `OffsetDateTime` object.
             .atZoneSameInstant(                   // Adjust into another time zone. The `sameInstant` part means the same moment, different wall-clock time. 
                 ZoneId.of( "Africa/Tunis" )       // Specify the particular zone of interest to you.
             )                                     // Returns a `ZonedDateTime` object.

Éviter java.util.Date & .Calendar

Ces classes héritées sont notoirement gênantes. Sun / Oracle a ajouté le java.temps package en Java 8 pour les supplanter. Ce paquet a été inspiré par Joda-Time.

Parmi les les problèmes des classes héritées sont ce comportement déroutant: Alors qu'un java.util.Date n'a pas d'informations de fuseau horaire, son implémentation toString applique le fuseau horaire par défaut actuel de la JVM lors de la génération d'une chaîne. Il vous induit donc en erreur en semblant avoir un fuseau horaire alors qu'il ne le fait pas.

Java.temps

J'essaie de convertir cette chaîne "2014-02-14T06:04:00:00", ...

Votre chaîne d'entrée n'a pas d'indicateur de fuseau horaire ou de décalage par rapport à l'UTC. Nous analysons donc comme un LocalDateTime, qui manque de tout concept de zone / décalage.

Un LocalDateTime ne pas représentent un moment, pas un point sur la timeline. Le mot "Local" ici ne pas signifie une localité spécifique. Cela signifie "pas de localité spécifique du tout". Sans le contexte d'une zone / offset, il n'a pas de véritable sens.

LocalDateTime ldt = LocalDateTime.parse( "2014-02-14T06:04:00:00" ) ;

Which qui est en GMT {

Vous dites que vous êtes certain que le fournisseur de cette chaîne d'entrée a prévu UTC comme contexte. Nous peut appliquer un offset-from-UTC de zéro, ou UTC lui-même, pour obtenir un objet OffsetDateTime. Un OffsetDateTime est un moment, un point sur la timeline. Nous pouvons spécifier le ZoneOffset en utilisant la constante pour UTC, ZoneOffset.UTC.

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;

... à mon fuseau horaire datetime

Apparemment, vous voulez ajuster ce moment dans un autre fuseau horaire, pour voir l'heure de l'horloge murale utilisée par les gens d'une région particulière. Nous devons appliquer un fuseau horaire (ZoneId) pour obtenir un ZonedDateTime.

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

Au Lieu de spécifier un fuseau horaire, vous pouvez demander à votre JVM son fuseau horaire par défaut. Attention: le fuseau horaire par défaut actuel de la JVM peut être modifié à tout moment par n'importe quel code dans n'importe quel thread de n'importe quelle application de cette JVM.

ZoneId z = ZoneId.systemDefault() ;
ZonedDateTime zdt = odt.atZone( z ) ;

Point est mon application sera utilisée dans différents endroits géographiques.

Spécifiez simplement vos fuseaux horaires souhaités/attendus explicitement. C'est toujours bonne pratique, dans mon avis. Le fuseau horaire par défaut est hors de votre contrôle en tant que programmeur, ce qui le rend peu fiable.

Spécifier un fuseau horaire nom dans le format continent/region, tels que America/Montreal, Africa/Casablanca, ou Pacific/Auckland. N'utilisez jamais l'abréviation de 3-4 lettres telle que EST ou ISTcar ce sont pas de vrais fuseaux horaires, non normalisés et même pas uniques(!).

Un autre conseil: Travailler, penser, stocker et échanger en UTC. Oubliez votre propre paroisse fuseau horaire, comme la traduction d'avant en arrière à votre zone d'origine vous conduira batty. Pensez à UTC comme le Un temps vrai , et les autres zones/décalages ne sont que de simples variations.

Instant instant = Instant.now() ;  // Capture current moment in UTC.

ZoneId zAuckland = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdtAuckland = instant.atZone( zAuckland ) ;

ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;  
ZonedDateTime zdtKolkata = instant.atZone( zKolkata ) ;

ZoneId zCasablanca = ZoneId.of( "Africa/Casablanca" ) ;  
ZonedDateTime zdtCasablanca = instant.atZone( zCasablanca ) ;

Il y a quatre façons ( instant, zdtAuckland, zdtKolkata, zdtCasablanca ) de regarder le même moment simultané, le même point sur la chronologie.

Éphémère.toString (): 2018-05-08T20:55: 14.761721 Z

ZdtAuckland.toString(): 2018-05-09T08:55:14.761721+12: 00[Pacifique/Auckland]

ZdtKolkata.toString (): 2018-05-09T02:25: 14.761721+05: 30[Asie/Calcutta]

ZdtCasablanca.toString (): 2018-05-08T21:55: 14.761721+01: 00[Afrique/Casablanca]

Zone vs Décalage

Un décalage par rapport à UTC est simplement un nombre d'heures, de minutes et de secondes. Rien de plus, rien de moins. N'importe quel nombre de fuseaux horaires peuvent partager un décalage particulier à un moment particulier.

Un fuseau horaire est une histoire de changements passés, présents et futurs de la compensation utilisée par les habitants d'une région particulière. Par exemple, l'heure d'été (DST) est une pratique où les habitants d'une région (inexplicablement) décident de changer leur décalage deux fois par an.

Un fuseau horaire est donc toujours préférable à un simple décalage. Avoir une zone nous permet d'ajouter ou de soustraire du temps de manière significative, pour tenir compte des changements de décalage dans l'histoire de cette région.


À propos de java.temps

Le java.temps framework est intégré à Java 8 et versions ultérieures. Ces classes permettent d'éviter la pénible vieux héritage date-heure classes telles que java.util.Date, Calendar, & SimpleDateFormat.

Le Joda-Temps le projet, maintenant en mode de maintenance, conseille la migration vers le java.temps classes.

Pour en savoir plus, voir le Tutoriel Oracle. Et rechercher un débordement de pile pour beaucoup des exemples et des explications. La spécification est JSR 310 .

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

Où obtenir le java.les classes de temps?

  • Java SE 8, Java SE 9, Java SE 10, et tard
    • 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 du java.la fonctionnalité time est back-ported vers Java 6 & 7 dans ThreeTen-Backport.
  • Android
    • Versions ultérieures des implémentations Android bundle de java.les classes de temps.
    • Pour Android antérieur (Troisabp le projet adapte ThreeTen-Backport (mentionné ci-dessus). Voir Comment utiliser ThreeTenABP....

Le Trois-Extra le projet étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'essai pour d'éventuels ajouts futurs à java.temps. Vous pouvez trouver quelques classes utiles ici comme Interval, YearWeek, YearQuarter, et plus.


Joda-Temps

MISE À JOUR: Le projet Joda-Time est maintenant en mode maintenance. L'équipe conseille la migration vers java.les classes de temps. Passez à java.section de temps ci - dessous dans ce Réponse.

Le paquet Joda-Time a un bon support clair pour les fuseaux horaires. Contrairement à java.util.Date, un Joda-Time DateTime connaît son propre fuseau horaire assigné. Si vous ne parvenez pas à spécifier un fuseau horaire, le fuseau horaire par défaut actuel de la JVM est implicitement affecté.

DateTime dateTime = DateTime.now(); // Applies JVM’s default time zone implicitly.

Je recommande de ne pas compter implicitement sur le fuseau horaire par défaut. Cela conduit à la confusion et aux erreurs lors du travail date-heure.

DateTime dateTime = DateTime.now( DateTimeZone.getDefault() ); // Explicitly using default time zone.

, Si nécessaire, vous pouvez attribuer un fuseau horaire.

DateTime dateTimeKolkata = DateTime.now( DateTimeZone.forID( "Asia/Kolkata" ) ); // Specify a time zone.

Pour côté serveur, la meilleure pratique consiste à faire de la logique métier et du stockage de base de données dans UTC.

DateTime dateTimeUtc = DateTime.now( DateTimeZone.UTC ); // Assign UTC (GMT) time zone.

Vous pouvez convertir du fuseau horaire assigné à un autre, y compris le fuseau horaire par défaut actuel de la JVM.

DateTime dateTime = dateTimeUtc.withZone( DateTimeZone.getDefault() );

Immuable

Pour la sécurité des threads, Joda-Time utilise des objets immuables. Au lieu de modifier un objet, des méthodes telles que withZone créent une nouvelle instance basée sur l'original.

Chaîne d'analyse

Pour analyser une chaîne comme un DateTime, vous devez noter si la chaîne comprend un décalage par rapport à UTC et / ou un fuseau horaire. La vôtre ne l'est pas. Vous devez donc spécifier un fuseau horaire par lequel interpréter cette chaîne. Si vous ne spécifiez pas, le fuseau horaire par défaut actuel de la JVM sera utilisé pendant l'analyse.

Dans votre question, vous avez dit que la chaîne représente une date-heure en UTC (GMT ).

DateTime dateTimeUtc = new DateTime( "2014-02-14T06:04:00:00", DateTimeZone.UTC );

Après l'analyse, vous pouvez assigner un autre fuseau horaire si nécessaire. Même moment dans la ligne de temps du Univers, mais montre un autre Horloge murale temps .

DateTime dateTimeDefaultZone = dateTimeUtc.withZone( DateTimeZone.getDefault() );

Notez donc qu'il s'agissait d'un processus en deux étapes. Tout d'abord, nous avons analysé votre chaîne en utilisant notre connaissance externe du fuseau horaire prévu de cette chaîne car il manquait de représentation interne de ce fuseau horaire ou de décalage. Deuxièmement, nous avons ajusté le fuseau horaire à un autre (la zone par défaut de la JVM).

Si votre chaîne avait inclus un décalage de +00:00 ou le Z habituel, nous aurions pu réduire ces deux étapes en un.

DateTime dateTimeDefaultZone = new DateTime(  "2014-02-14T06:04:00:00Z", DateTimeZone.getDefault() ); // Apply time zone adjustment *after* parsing.

Notez que ce constructeur DateTime ressemble à celui ci-dessus mais est en fait assez différent. L'argument de fuseau horaire de celui-ci est appliqué après l'analyse, plutôt que pendant l'analyse. Ici, l'argument fuseau horaire est utilisé pour ajuster le DateTime déjà analysé. Ce Z à la fin fait un monde de différence.

Source du fuseau horaire par défaut

La JVM obtient initialement son fuseau horaire par défaut du système d'exploitation hôte. Mais sachez qu'un programmeur peut remplacer cela par:

Cette substitution affecte tous les threads de toutes les applications exécutées dans cette JVM. Vous devez donc savoir que le fuseau horaire par défaut de la JVM est généralement le même que le système d'exploitation hôte, mais pas nécessairement le même.

 37
Author: Basil Bourque, 2018-05-08 21:02:09

Je crois que ce que vous cherchez est le Joda bibliothèque. Il a une fonctionnalité meilleure que les classes de calendrier ou de date comme spécifié dans la réponse ici.

Cette fonction devrait être particulièrement utile.

 0
Author: BCza, 2017-05-23 12:02:37
      private String receivedFormat = "yyyy-MM-dd'T'HH:mm:ss", expectedFormat = "dd-MM-yyyy HH:mm:ss"; //Globall variables

        //Write these three lines in your Test Class and below 2 methods

        String dateString = "2018-08-14T07:00:00:00";
        String returnString = correctDateFormat(dateString, receivedFormat, expectedFormat);
        String result = getTimeInSelectedLocale(returnString);
    Log.i("Ayaz", "Date: " +result);



     /**
         * @param receivedDate
         * @param givenFormat
         * @param expectedFormat
         * @return returns date time in expected format
         */
        public static String correctDateFormat(String receivedDate, String givenFormat, String expectedFormat) {
            if (TextUtils.isEmpty(receivedDate)) {
                return "";
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(givenFormat);
            Date newDate = null;
            try {
                newDate = simpleDateFormat.parse(receivedDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            simpleDateFormat = new SimpleDateFormat(expectedFormat);
            receivedDate = simpleDateFormat.format(newDate);
            return receivedDate;
        }



        /**
         * @param dateString
         * @return passed string date in different locale, My Db is in IST so I an converting IST in different locale
         */
        public  String getTimeInSelectedLocale(String dateString) {
            if (TextUtils.isEmpty(dateString)) {
                return dateString;
            }
            SimpleDateFormat sdf = new SimpleDateFormat(expectedFormat);
            sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata")); //We want Indian time to change in different locale, so this line is compulsory, you can replace with your country
            Date date1 = null;
            try {
                date1 = sdf.parse(dateString);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            //below this line -> TimeZone.getTimeZone(TimeZone.getDefault().getID(), will return current locale for example for India "Asia/Kolkata" for UAE "Asia/Dubai"
            sdf.setTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID())); //This line chooses current local in which you want time
            String localDate = sdf.format(date1);
            return localDate;
        }

//I am converting the IST time "2018-08-14T07:00:00:00"  into UAE(Duabai) "14-08-2018 05:30:00" and other countries
 0
Author: Ayaz, 2018-08-06 06:43:30