A java.util.Date
doesn't have any timezone information. Une fois que vous désérialisez un String
en Date
, le décalage +0300
est perdu: la date conserve uniquement la valeur d'horodatage et ne peut pas savoir quel est le fuseau horaire d'origine.
Si la sortie doit toujours être en +03:00
décalage, vous pouvez définir directement dans les champs respectifs, en utilisant la com.fasterxml.jackson.annotation.JsonFormat
annotation:
@JsonFormat(timezone = "GMT+03:00")
private Date startDateTime;
@JsonFormat(timezone = "GMT+03:00")
private Date endDateTime;
Avec cela, les champs de date seront toujours sérialisés à +03:00
offset:
{
"startDateTime":"2017-10-09T22:43:07.109+0300",
"endDateTime":"2017-10-09T21:40:07.109+0300"
}
Si les entrées peuvent être tout autre décalage (non seulement +03:00
) et vous voulez le préserver, le java.util.Date
n'est pas le type idéal. Une alternative consiste à utiliser Jackson Modules Java 8, si vous utilisez Java> = 8.
Pour Java 6 et 7, il y a le ThreeTen Backport et correspondant Jackson module - Je ne l'ai pas testé, mais, mais le code peut être similaire , car le BackTort ThreeTen contient les mêmes classes et méthodes, seul le package est différent - (Java 8 est java.time
et dans ThreeTen Backport est org.threeten.bp
).
Pour préserver la date, l'heure et le décalage, la meilleure alternative est la classe OffsetDateTime
. Donc, il vous suffit de modifier les champs de type et définir le format qui lui correspond:
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXX")
private OffsetDateTime startDateTime;
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXX")
private OffsetDateTime endDateTime;
Dans le mappeur d'objets, vous devez également enregistrer le JavaTimeModule
et désactiver le ADJUST_DATES_TO_CONTEXT_TIME_ZONE
feature, de sorte que les décalages sont préservés (le comportement par défaut est pour convertir au fuseau horaire du contexte de Jackson, qui pourrait ne pas être le même utilisé dans les entrées - en désactivant ceci, le décalage est préservé).
Vous pouvez utiliser un JacksonConfigurator
(comme explained in this answer) et faire ces configurations:
ObjectMapper om = new ObjectMapper();
om.registerModule(new JavaTimeModule());
om.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
Cette configuration est généralement suffisant, mais vous pouvez également définir SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
-false
aussi bien, juste au cas où.
Si vous avez besoin de travailler avec java.util.Date
, vous pouvez utiliser l'API pour convertir de/vers elle. En Java 8, il y a la nouvelle méthode Date.from
:
// convert to java.util.Date
public Date getStartAsJavaUtilDate() {
return Date.from(startDateTime.toInstant());
}
Et ThreeTen Backport, il y a la classe org.threeten.bp.DateTimeUtils
:
// convert to java.util.Date
DateTimeUtils.toDate(startDateTime.toInstant());
Pour convertir un Date
retour à OffsetDateTime
, cependant, il est plus délicat. L'objet Date
n'a pas d'informations de fuseau horaire, il ne peut donc pas connaître le décalage d'origine. Une alternative consiste à maintenir le décalage d'origine dans une variable séparée:
// keep the original offset
ZoneOffset startDateOffset = startDateTime.getOffset();
Ensuite, vous pouvez convertir le Date
à Instant
, puis le convertir à l'original offset:
// convert java.util.Date to original offset (Java 8)
startDateTime = date.toInstant().atOffset(startDateOffset);
// ThreeTen Backport
startDateTime = DateTimeUtils.toInstant(date).atOffset(startDateOffset);
usage classe DateTime qui est plus approprié pour ce cas – CodeIsLife
Avez-vous utilisé l'annotation 'JsonFormat' si les champs' OffsetDateTime' (comme dans ma réponse ci-dessous)? –
Oui, j'ai ajouté cette annotation, mais ne fonctionnait toujours pas – Habchi