Je télécharge des données JSON à partir d'un service Web. Dans ce JSON, j'ai des valeurs de date/heure. Tout en UTC . Comment puis-je analyser cette chaîne de date pour que l’objet Date de résultat se trouve dans les paramètres régionaux en cours?
Par exemple: le serveur a renvoyé "2011-05-18 16:35:01" et mon appareil doit maintenant afficher "2011-05-18 18:35:01" (GMT +2).
Mon code actuel:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));
Il a une méthode de fuseau horaire définie:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));
terminé!
Vous souhaitez donc informer SimpleDateFormat du fuseau horaire UTC:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TimeZone utcZone = TimeZone.getTimeZone("UTC");
simpleDateFormat.setTimeZone(utcZone);
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));
Afficher:
simpleDateFormat.setTimeZone(TimeZone.getDefault());
String formattedDate = simpleDateFormat.format(myDate);
Votre chaîne myUTC = "2016-02-03T06: 41: 33.000Z"
SimpleDateFormat existingUTCFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
SimpleDateFormat requiredFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
Date getDate = existingFormat.parse(myUTC);
String mydate = requiredFormat.format(getDate)
}
catch(ParseException){
}
Java.time
Je voudrais apporter la réponse moderne. La plupart des autres réponses sont correctes et étaient correctes en 2011. Aujourd'hui, SimpleDateFormat
est depuis longtemps obsolète, et il y a toujours eu des surprises. Et aujourd'hui, nous avons tellement mieux: Java.time
également connu sous le nom de JSR-310, l'API de date et heure moderne de Java. Cette réponse s'adresse à quiconque accepte une dépendance externe (jusqu'à ce que Java.time
apparaisse sur votre appareil Android) ou utilise déjà Java 8 ou une version ultérieure.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String dateTimeFromServer = "2011-05-18 16:35:01";
String localTimeToDisplay = LocalDateTime.parse(dateTimeFromServer, formatter)
.atOffset(ZoneOffset.UTC)
.atZoneSameInstant(ZoneId.of("Europe/Zurich"))
.format(formatter);
Le résultat de cet extrait de code correspond à ce qui a été demandé:
2011-05-18 18:35:01
Indiquez le fuseau horaire si vous le pouvez
J'ai donné un fuseau horaire explicite Europe/Zurich. S'il vous plaît substituer votre fuseau horaire local désiré. Pour utiliser les paramètres de fuseau horaire de votre appareil, utilisez ZoneId.systemDefault()
. Toutefois, sachez que ceci est fragile car il prend le paramètre de fuseau horaire de la machine virtuelle Java et ce paramètre peut être modifié sous nos pieds par d'autres parties de votre programme ou par d'autres programmes exécutés sur la même machine virtuelle.
Utilisation de Java.time sur Android
Je vous ai promis une dépendance externe. Pour utiliser ce qui précède sur Android, vous avez besoin de ThreeTenABP, l’édition Android de ThreeTen Backport, le backport de JSR-310 à Java 6 et 7. Comment le faire est expliqué en détail dans cette question: Comment utiliser ThreeTenABP dans le projet Android .
public static String toLocalDateString(String utcTimeStamp) {
Date utcDate = new Date(utcTimeStamp);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
df.setTimeZone(TimeZone.getTimeZone("PST"));
return df.format(utcDate);
}
À votre santé!
Si vous aviez plutôt un horodatage (long) (pour l'heure UTC), puisqu'il s'agit d'Android, vous pouvez faire quelque chose comme ça:
fun DateFormat.formatUtcEpochSecond(epochSecond: Long): String = format(CalendarEx.getFromEpochSecond(epochSecond).time)
fun DateFormat.formatUtcEpochMs(epochMilli: Long): String = format(CalendarEx.getFromEpochMilli(epochMilli).time)
CalendarEx.kt
object CalendarEx {
@JvmStatic
fun getFromEpochMilli(epochMilli: Long): Calendar {
val cal = Calendar.getInstance()
cal.timeInMillis = epochMilli
return cal
}
@JvmStatic
fun getFromEpochSecond(epochSecond: Long): Calendar {
val cal = Calendar.getInstance()
cal.timeInMillis = epochSecond * 1000L
return cal
}
}
DateHelper.kt
/**
* gets the default date formatter of the device
*/
@JvmStatic
fun getFormatDateUsingDeviceSettings(context: Context): Java.text.DateFormat {
return DateFormat.getDateFormat(context) ?: SimpleDateFormat("yyyy/MM/dd", Locale.getDefault())
}
/**
* gets the default time formatter of the device
*/
@JvmStatic
fun getFormatTimeUsingDeviceSettings(context: Context): Java.text.DateFormat {
return DateFormat.getTimeFormat(context) ?: SimpleDateFormat("HH:mm", Locale.getDefault())
}
Exemple d'utilisation:
val dateFormat = DateHelper.getFormatDateUsingDeviceSettings(this)
val timeFormat = DateHelper.getFormatTimeUsingDeviceSettings(this)
val timeStampSecondsInUtc = 1516797000L
val localDateTime = Instant.ofEpochSecond(timeStampSecondsInUtc).atZone(ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0))).toLocalDateTime()
Log.d("AppLog", "input time in UTC:" + localDateTime)
Log.d("AppLog", "formatted date and time in current config:${dateFormat.formatUtcEpochSecond(timeStampSecondsInUtc)} ${timeFormat.formatUtcEpochSecond(timeStampSecondsInUtc)}")
Un objet Date est toujours un wrapper autour de millisecondes depuis Epoch 0 en UTC. Il ne représente jamais l'heure locale.
Cela signifie que vous devez créer un deuxième SimpleDateFormatter qui crée une chaîne d'affichage en heure locale.
Edit: @Op. Notez que la classe préférée pour le formatage date/heure sur Android est Java.text.DateFormat