2017-09-01 5 views
0

Je suis en train de convertir UTC à l'heure locale,Java UTC à l'heure locale ne fonctionne pas

est Ci-dessous le code que je me sers,

public static String utcToLocalDateFormat(String dateString) { 

     Log.i("DateFormat", "utcToLocal:Before===>" + dateString); 

     String formattedDate = null; 
     if (dateString != null) { 
      DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
      dateFormat.setTimeZone(TimeZone.getDefault()); 
      Date date = null; 
      try { 

       Log.i("DateFormat", "getTimeZone===>" +dateFormat.getTimeZone()); 
       date = dateFormat.parse(dateString); 
       System.out.println(date); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 
      formattedDate = dateFormat.format(date); 
      Log.i("DateFormat", "utcToLocal:After===>" + formattedDate); 

     } 
     return formattedDate; 
    } 

Mais le problème est avant et après le temps de conversion de fuseau horaire est même.Il ne convertit pas en UTC à l'heure locale. Toute aide appréciée.

Voici mes entrée: 1) 2017-08-31 20:40:59 2) 2017-09-01 11: 16: 24,024

sortie suivant: 1) 2017-08- 31 20:40:59 2) 2017-09-01 11:16:24

+1

Pourriez-vous s'il vous plaît fournir des entrées et des sorties (attendu vs ce que vous obtenez)? –

+1

Est-il correct que votre 'dateFormat' analyse l'entrée en tant que TZ locale? – yegodm

+0

Dans votre modèle de format de date, vous n'avez aucune information dans quel fuseau horaire il sera transmis à votre méthode. Ainsi, la chaîne est analysée car elle est déjà dans le fuseau horaire par défaut. – Damian0o

Répondre

0

Changer la ligne

dateFormat.setTimeZone(TimeZone.getDefault()); 

à

dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
2

Quand vous faites:

dateFormat.setTimeZone(TimeZone.getDefault()); 

Et puis analyser le String, vous dites au formatter: « Je vais vous donner une chaîne avec une date et l'heure dans ce fuseau horaire ». Comme vous avez utilisé TimeZone.getDefault(), il utilisera le fuseau horaire par défaut de la JVM. La première chose est de dire la formatter à utiliser UTC lors de l'analyse:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use UTC to parse 
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
.... 
date = dateFormat.parse(dateString); 

Je teste avec dateString égale à 2017-08-01 10:00:00. Ainsi, le date sera équivalent à 2017-08-01 10:00:00 UTC. Lorsque vous imprimez la date avec System.out.println, il appelle le toString() et le convertit dans le fuseau horaire par défaut de la JVM.

Dans la machine virtuelle Java J'utilise, le fuseau horaire par défaut est America/Sao_Paulo, quand j'appelle cela:

System.out.println(date); 

Il imprime:

Mar 1 août 2017 07:00:00 BRT

Parce que en 1 Août st, 10 heures UTC équivaut à 7 heures à São Paulo. Ce résultat changera en fonction du fuseau horaire par défaut de votre JVM,.

Si vous souhaitez imprimer cette date, mais avec la date et l'heure équivalent à un autre fuseau horaire (autre que UTC), vous aurez besoin d'un autre formatter avec un autre jeu de fuseau horaire:

DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use my default timezone to format (America/Sao_Paulo) 
dateFormat2.setTimeZone(TimeZone.getDefault()); 
formattedDate = dateFormat2.format(date); 

Ce imprimera:

2017-08-01 07:00:00

au lieu du fuseau horaire par défaut, vous pouvez utiliser ce que fuseau horaire que vous voulez (j'utilise America/New_York comme exemple):

DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use New York timezone 
dateFormat2.setTimeZone(TimeZone.getTimeZone("America/New_York")); 
formattedDate = dateFormat2.format(date); 

Ceci convertira la date/heure au fuseau horaire de New York:

2017-08-01 06:00:00

Si vous voulez imprimer la date/heure en UTC, alors vous n'avez pas besoin de créer un autre formateur, utilisez simplement le premier (car il est déjà défini sur UTC).


Le fuseau horaire par défaut de JVM can be changed without notice, even at runtime, il est donc préférable d'utiliser un spécifique au lieu d'utiliser getDefault().

Préférez utiliser IANA timezones names (toujours au format Region/City, comme America/Sao_Paulo ou Europe/Berlin). Évitez d'utiliser les abréviations à 3 lettres (comme CST ou) car elles sont ambiguous and not standard.

Vous pouvez obtenir la liste des fuseaux horaires disponibles (et choisir celle qui correspond le mieux à votre système) en appelant TimeZone.getAvailableIDs().


nouvelle date/API Temps

Les anciennes classes (Date, Calendar et SimpleDateFormat) ont lots of problems et design issues, et ils sont remplacés par les nouvelles API.

Dans Android, vous pouvez utiliser le ThreeTen Backport, un excellent backport pour les nouvelles classes date/heure de Java 8. Pour le faire fonctionner, vous aurez également besoin de ThreeTenABP (plus sur comment l'utiliser here).

Cette API est beaucoup plus facile à utiliser. D'abord, créez un org.threeten.bp.format.DateTimeFormatter et analysez l'entrée String en org.threeten.bp.LocalDateTime.

Ensuite, vous le convertir en UTC (création d'un org.threeten.bp.ZonedDateTime), puis le fuseau horaire que vous voulez et utilisez un autre formatter pour le sortir:

// date/time with optional milliseconds 
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS]"); 
// parse to LocalDateTime 
LocalDateTime dt = LocalDateTime.parse(dateString, parser); 

// convert to UTC 
ZonedDateTime z = dt.atZone(ZoneOffset.UTC); 

// convert to another timezone 
z = z.withZoneSameInstant(ZoneId.of("America/New_York")); 
// format it 
// date/time without milliseconds 
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 
System.out.println(fmt.format(z)); 

Vous pouvez également utiliser le fuseau horaire par défaut en utilisant ZoneId.systemDefault(), et obtenir tous les fuseaux horaires disponibles avec ZoneId.getAvailableZoneIds().

Si vous voulez la date/heure en UTC, vous pouvez passer l'appel à withZoneSameInstant().


Pour convertir en un java.util.Date, vous pouvez utiliser la classe org.threeten.bp.DateTimeUtils:

// convert ZonedDateTime to java.util.Date 
Date d = DateTimeUtils.toDate(z.toInstant()); 
+0

Merci, mais je ne veux pas spécifier le fuseau horaire comme (TimeZone.getTimeZone ("America/New_York")) ce que vous avez mentionné, Mon application a utilisé n'importe quelle partie du monde, il devrait fonctionner en fonction de ce fuseau horaire. – Joe

+0

@Joe J'ai mis à jour la réponse pour le rendre plus clair. –