Je n'arrive pas à obtenir gson pour convertir une date en heure UTC en Java .... Voici mon code ...
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();
//This is the format I want, which according to the ISO8601 standard - Z specifies UTC - 'Zulu' time
Date now=new Date();
System.out.println(now);
System.out.println(now.getTimezoneOffset());
System.out.println(gson.toJson(now));
Voici ma sortie
Thu Sep 25 18:21:42 BST 2014 // Time now - in British Summer Time
-60 // As expected : offset is 1hour from UTC
"2014-09-25T18:21:42.026Z" // Uhhhh this is not UTC ??? Its still BST !!
Le résultat gson que je veux et ce que j'attendais
"2014-09-25T17:21:42.026Z"
Je peux clairement soustraire 1 heure avant l'appel à Json, mais cela semble être un hack. Comment puis-je configurer gson pour toujours convertir en UTC?
Après quelques recherches supplémentaires, il semble que ce soit un problème connu. Le sérialiseur par défaut de gson est toujours défini par défaut sur votre fuseau horaire local et ne vous permet pas de spécifier le fuseau horaire. Voir le lien suivant .....
https://code.google.com/p/google-gson/issues/detail?id=281
La solution consiste à créer un adaptateur de type gson personnalisé, comme illustré dans le lien:
// this class can't be static
public class GsonUTCDateAdapter implements JsonSerializer<Date>,JsonDeserializer<Date> {
private final DateFormat dateFormat;
public GsonUTCDateAdapter() {
dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); //This is the format I need
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); //This is the key line which converts the date to UTC which cannot be accessed with the default serializer
}
@Override public synchronized JsonElement serialize(Date date,Type type,JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(dateFormat.format(date));
}
@Override public synchronized Date deserialize(JsonElement jsonElement,Type type,JsonDeserializationContext jsonDeserializationContext) {
try {
return dateFormat.parse(jsonElement.getAsString());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}
}
Enregistrez-le ensuite comme suit:
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new GsonUTCDateAdapter()).create();
Date now=new Date();
System.out.println(gson.toJson(now));
Cela affiche désormais correctement la date en UTC
"2014-09-25T17:21:42.026Z"
Merci à l'auteur du lien.
La solution qui a fonctionné pour moi pour ce problème était de créer un adaptateur de date personnalisé (faites attention à P.S afin d'importer Java.util.Date
ne pas Java.sql.Date
!)
public class ColonCompatibileDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer< Date> {
private final DateFormat dateFormat;
public ColonCompatibileDateTypeAdapter() {
dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") {
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {
StringBuffer rfcFormat = super.format(date, toAppendTo, pos);
return rfcFormat.insert(rfcFormat.length() - 2, ":");
}
@Override
public Date parse(String text, ParsePosition pos) {
if (text.length() > 3) {
text = text.substring(0, text.length() - 3) + text.substring(text.length() - 2);
}
return super.parse(text, pos);
}
};
}
@Override public synchronized JsonElement serialize(Date date, Type type,
JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(dateFormat.format(date));
}
@Override public synchronized Date deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) {
try {
return dateFormat.parse(jsonElement.getAsString());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}}
puis l'utiliser lors de la création d'un objet GSON
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new ColonCompatibileDateTypeAdapter()).create();
Le Z dans votre format de date est entre guillemets simples, il doit être sans guillemets pour être remplacé par le fuseau horaire réel.
De plus, si vous voulez que votre date soit en UTC, convertissez-la d'abord.
J'ai adapté le solution marqué et paramétré le DateFormat
:
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import Java.lang.reflect.Type;
import Java.text.DateFormat;
import Java.text.ParseException;
import Java.util.Date;
public class GsonDateFormatAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final DateFormat dateFormat;
public GsonDateFormatAdapter(DateFormat dateFormat) {
this.dateFormat = dateFormat;
}
@Override
public synchronized JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(dateFormat.format(date));
}
@Override
public synchronized Date deserialize(JsonElement jsonElement, Type type,JsonDeserializationContext jsonDeserializationContext) {
try {
return dateFormat.parse(jsonElement.getAsString());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}
}