web-dev-qa-db-fra.com

Java: Comment convertir un horodatage UTC en heure locale?

J'ai un horodatage qui est en UTC et je veux le convertir en heure locale sans utiliser un appel d'API comme TimeZone.getTimeZone("PST"). Comment êtes-vous censé faire exactement cela? J'ai utilisé le code suivant sans grand succès:

private static final SimpleDateFormat mSegmentStartTimeFormatter = new        SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

Calendar calendar = Calendar.getInstance();

    try {
        calendar.setTime(mSegmentStartTimeFormatter.parse(startTime));
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return calendar.getTimeInMillis();

Exemple de valeur d'entrée: [2012-08-15T22:56:02.038Z]

devrait renvoyer l'équivalent de [2012-08-15T15:56:02.038Z]

30
Android Noob

Date n'a pas de fuseau horaire et stocke en interne en UTC. La correction du fuseau horaire s'applique uniquement lorsqu'une date est formatée. Lorsque vous utilisez un DateFormat, il correspond par défaut au fuseau horaire de la machine virtuelle Java dans laquelle il s'exécute. Utilisez setTimeZone pour le modifier si nécessaire.

DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

Date date = utcFormat.parse("2012-08-15T22:56:02.038Z");

DateFormat pstFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
pstFormat.setTimeZone(TimeZone.getTimeZone("PST"));

System.out.println(pstFormat.format(date));

Cela imprime 2012-08-15T15:56:02.038

Notez que j'ai omis le 'Z' au format PST car il indique UTC. Si vous venez d'utiliser Z, la sortie sera 2012-08-15T15:56:02.038-0700

49
Steve Kuo

Utilisez la moderne Java API date et heure, et c'est simple:

    String inputValue = "2012-08-15T22:56:02.038Z";
    Instant timestamp = Instant.parse(inputValue);
    ZonedDateTime losAngelesTime = timestamp.atZone(ZoneId.of("America/Los_Angeles"));
    System.out.println(losAngelesTime);

Ceci imprime

2012-08-15T15:56:02.038-07:00[America/Los_Angeles]

Points à noter:

  • Il y a un petit bug dans vos attentes. Z dans votre horodatage signifie UTC, également appelé heure zoulou. Donc, dans votre valeur d'heure locale, le Z ne devrait pas être là. Vous voudriez plutôt une valeur de retour comme par exemple 2012-08-15T15:56:02.038-07:00, car le décalage est désormais de -7 heures au lieu de Z.
  • Évitez les abréviations de fuseau horaire à trois lettres. Ils ne sont pas standardisés et donc le plus souvent ambigus. PST, par exemple, peut signifier l'heure standard philppine, l'heure standard du Pacifique ou l'heure standard de Pitcairn (bien que S dans une abréviation soit souvent pour l'heure d'été (ce qui signifie DST)). Si vous vouliez l'heure standard du Pacifique, ce n'est même pas un fuseau horaire, car en été (là où votre horodatage tombe), l'heure d'été du Pacifique est utilisée à la place. Au lieu des abréviations, utilisez des ID de fuseau horaire au format région/ville comme dans mon code.
  • Les horodatages sont généralement mieux gérés en tant qu'objets Instant. Convertissez en ZonedDateTime uniquement lorsque vous en avez besoin, comme pour la présentation.

Question: Puis-je utiliser l'API moderne avec ma Java?

Si vous utilisez au moins Java 6 , vous le pouvez.

  • Dans Java 8 et versions ultérieures, la nouvelle API est intégrée.
  • Dans Java 6 et 7 get le port arrière ThreeTen , le port arrière des nouvelles classes (c'est ThreeTen pour JSR-310, où l'API moderne a été définie pour la première fois).
  • Sur Android, utilisez l'édition Android Android de ThreeTen Backport. Elle s'appelle ThreeTenABP, et je pense qu'il y a une merveilleuse explication dans cette question: comment utiliser ThreeTenABP dans Android Project .
13
Ole V.V.