web-dev-qa-db-fra.com

Utilisation de Joda-Time pour obtenir un décalage UTC pour une date et un fuseau horaire donnés

J'ai des dates au format 20janvier 2013, 08 août 2012, etc., avec leurs propres fuseaux horaires. Ainsi, par exemple, 20Jan2013 pourrait avoir un identifiant de fuseau horaire Australie/Melbourne, et 08Aug2012 pourrait avoir un identifiant Europe/Londres. Ce que je veux faire est, en fonction de ces fuseaux horaires et des dates, calculer le décalage UTC pour ce fuseau horaire à la date donnée. Je suis venu avec cela jusqu'à présent:

DateTimeFormatter dtf = DateTimeFormat.forPattern("ZZ");
DateTimeFormatter dtf1 = DateTimeFormat.forPattern("ddMMMYYYY");

DateTimeZone zone = DateTimeZone.forID("Australia/Melbourne");  

DateTime thisDate = dtf1.parseDateTime("30Jul2013");                                            
System.out.println("\nZone: " + thisDate.withZone(zone));

Cela me donne la sortie: 

Zone: 2013-07-30T00:00:00.000+10:00

C’est correct, mais j’aimerais extraire uniquement le décalage UTC, qui dans ce cas est +10: 00. J'ai cherché des moyens de le faire mais je ne trouve rien. Y a-t-il un moyen de faire ça? La seule option que je vois est de convertir la sortie en chaîne et d'utiliser la méthode de la sous-chaîne pour obtenir le décalage UTC.

Le code ci-dessus prend en compte l'heure d'été (DST). Ainsi, par exemple, si j'avais: DateTime thisDate = dtf1.parseDateTime ("30Jan2013"); 

La sortie serait: 2013-01-30T00: 00: 00.000 + 11: 00 

(+11: 00 à la fin au lieu de +10: 00) 

Donc, tout ce que j'ai à faire, c'est trouver un moyen d'extraire +11: 00 du 2013-07-30T00: 00: 00.000 + 11: 00. S'il vous plaît aider!

13
PrincessBelle

Méthode simple pour obtenir un nom de fuseau horaire et un décalage en heures

public static String getCurrentTimeZoneOffset() {
    DateTimeZone tz = DateTimeZone.getDefault();
    Long instant = DateTime.now().getMillis();

    String name = tz.getName(instant);

    long offsetInMilliseconds = tz.getOffset(instant);
    long hours = TimeUnit.MILLISECONDS.toHours( offsetInMilliseconds );
    String offset = Long.toString( hours );

    return name + " (" + offset + " Hours)";
    // Example: "Mountain Standard Time (-7 Hours)"
}

Mises en garde de couple:

  • Ceci obtient la valeur par défaut DateTimeZone de JodaTime . Vous pouvez le modifier pour accepter un DateTimeZone spécifique transmis à la méthode.
  • Cela le renvoie dans un format du type " Heure normale des Rocheuses (-7 heures) " mais vous pouvez le formater comme bon vous semble.

J'espère que cela pourra aider. 

JP

11
Joshua Pinter

Pour que Joda fournisse le décalage correct, vous devez fournir un instant datetime. Sans un instant datetime, il est impossible de calculer le décalage car nous avons différents décalages (heure avancée). C'est ainsi que j'utiliserais Joda pour obtenir un décalage au format + HH: mm:

    int offsetInMillis = DateTimeZone.forID(zoneId).getOffset(new DateTime().getMillis());
    String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000),
            Math.abs((offsetInMillis / 60000) % 60));
    offset = (offsetInMillis >= 0 ? "+" : "-") + offset; 
3
Shweta

Si vous avez juste besoin du décalage de fuseau horaire, utilisez DateTimeZone.forID() pour obtenir le fuseau horaire, puis tz.getOffset(instant) pour obtenir le décalage par rapport à UTC en millisecondes.

Il peut sembler étrange que vous ayez besoin d’un instant pour calculer le décalage par rapport au temps UTC, mais il est nécessaire de prendre en compte l’heure avancée ainsi que les modifications du fuseau horaire. Oui, les pays changent de fuseau horaire de temps en temps:

Pourquoi les données de fuseau horaire changent?

Les paramètres de fuseau horaire sont adoptés localement et il n'y a pas d'autorité de fuseau horaire mondial. 

EDITCeci vous donne le résultat correct:

    DateTimeFormatter dtf1 = DateTimeFormat.forPattern("ddMMMYYYY");

    DateTimeZone zone = DateTimeZone.forID("Australia/Melbourne");  

    DateTime thisDate = dtf1.parseDateTime("30Jul2013").withZone(zone);                                            
    assertEquals( 10 * CommonConstants.MILLISECONDS_PER_HOUR,
        zone.getOffset( thisDate ) );

thisDate.get

3
Aaron Digulla

Java 8 a introduit une meilleure gestion de la date et de l'heure pour répondre à certaines des limitations précédentes du langage dans ce domaine. Certains de mes projets ont commencé à l'utiliser plutôt que Joda. 

Utilisation du package Java.time:

    ZonedDateTime dateTime = LocalDate.of(2013 , 1 , 20).atStartOfDay( ZoneId.of("Australia/Melbourne"));
    ZoneOffset zo = dateTime.getOffset();
    int offset = zo.getTotalSeconds();

    long hours = TimeUnit.SECONDS.toHours(offset);
    long minutes = TimeUnit.SECONDS.toMinutes(offset % 3600);

La variable heures est définie sur 11 et les minutes sur 0.

Il calcule également le décalage minutes, pour les fuseaux horaires partiellement définis, comme Terre-Neuve-et-Labrador dans l'est du Canada:

ZonedDateTime dateTime = LocalDate.of(2013, 1, 20).atStartOfDay( ZoneId.of("Canada/Newfoundland"));

Dans ce cas, le décalage est -03:30 (trois heures et demie après UTC), hours est -3 et minutes est -30.

Pour la représentation String, plutôt que le nombre entier d'heures et de minutes, utilisez la méthode toString () de ZoneOffset. Donc, pour l'exemple ci-dessus, utilisez:

String offsetString = zo.toString();
1
sjgp

Lorsque vous connaissez le décalage et l’horodatage, vous pouvez utiliser

 public static String formatMonthDayMinuteByGivenUtcOffset(long timestamp, int offset) {
        return JODA_FORMATTER.print(createDateTime(timestamp, offset));
    }
0
Waran-