2017-10-09 2 views
1

私は、日付を処理するスプリングブートアプリケーションを開発しています。私はstartDateTimeendDateTimeを(どちらがタイプjava.util.Dateである)を持つAppointmentオブジェクトを送信すると私はこのような形式を送信します日付のタイムゾーン、スプリングブートとジャクソン

{ 
    "lastName": "Jhon", 
    "firstName": "Doe", 
    "email": "[email protected]", 
    "description": "MyDescription", 
    "startDateTime": "2017-10-09T22:43:07.109+0300", 
    "endDateTime": "2017-10-09T21:40:07.109+0300", 
} 

データはデータベースに保存されている場合、私がしようとすると、それは、正しいタイムゾーンでです

"startDateTime": "2017-10-09T19:43:07.109+0000", 
"endDateTime": "2017-10-09T18:40:07.109+0000", 

がどのように私はジャクソンが付属していますタイムゾーンの使用状況を作るために設定することができます:私はしかし、デバッグしていたとき、彼らは私が値としてこれらとの出力を持つジャクソンによってシリアライズされると、彼らは、正しいように見える、戻って私のデータを取得私のリポジトリからのデータ?

------更新---------

私はOffsetDateTimeと答えを試みたが、出力はかなり奇妙です:

"startDateTime": { 
     "offset": { 
      "totalSeconds": 7200, 
      "id": "+02:00", 
      "rules": { 
       "fixedOffset": true, 
       "transitionRules": [], 
       "transitions": [] 
      } 
     }, 
     "month": "OCTOBER", 
     "year": 2017, 
     "hour": 21, 
     "minute": 49, 
     "nano": 654000000, 
     "second": 15, 
     "dayOfMonth": 9, 
     "dayOfWeek": "MONDAY", 
     "dayOfYear": 282, 
     "monthValue": 10 
    } 

私が何かを持っているしたいと思います等:

2017-10-09T22:43:07.109 + 0300

+0

使用DateTimeクラスである一つの選択肢は、別の変数に元のオフセットを維持することですこのケースにもっと適しています – CodeIsLife

+0

'OffsetDateTime'フィールドが(以下の私の答えにあるように)' JsonFormat'アノテーションを使用しましたか? –

+0

はい、私はこの注釈を追加しましたが、それでも動作しませんでした – Habchi

答えて

2

java.util.Datedoesn't have any timezone informationStringDateにデシリアライズすると、オフセット+0300が失われます。日付はタイムスタンプ値のみを保持し、元のタイムゾーンを知ることはできません。

出力は常にオフセット+03:00にする必要がある場合は、あなたがcom.fasterxml.jackson.annotation.JsonFormat注釈使用して、各フィールドに直接設定することができます。これにより

@JsonFormat(timezone = "GMT+03:00") 
private Date startDateTime; 

@JsonFormat(timezone = "GMT+03:00") 
private Date endDateTime; 

を、日付フィールドは常にオフセット+03:00にシリアライズされます。

{ 
    "startDateTime":"2017-10-09T22:43:07.109+0300", 
    "endDateTime":"2017-10-09T21:40:07.109+0300" 
} 

入力がであることができる場合は、他のオフセット(のみならず+03:00)とあなたがそれを保存したい場合、java.util.Dateは理想的なタイプではありません。一つの選択肢はJackson Modules Java 8を使用することです、あなたは、Java 6および7の場合> = 8

のJavaを使用している場合、ThreeTen Backportと対応Jackson moduleがあります - でも、私はテストしていませんが、コードは似ているかもしれませんThreeTenバックポートには同じクラスとメソッドが含まれているため、パッケージのみが異なります(Java 8ではjava.time、ThreeTen Backportではorg.threeten.bpです。

日付、時刻、オフセットを保持するには、OffsetDateTimeクラスが最適です。だから、あなただけのタイプとそれに対応するフォーマットを設定するフィールドを変更する必要があります。

@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; 

オブジェクトマッパーでは、あなたもJavaTimeModuleを登録する必要がありますし、オフセットが保存されているので、ADJUST_DATES_TO_CONTEXT_TIME_ZONE featureを無効にする(デフォルトの動作です入力に使用されていない可能性があるJacksonコンテキストのタイムゾーンに変換する - これを無効にすると、オフセットは保存されます)。

あなたはJacksonConfiguratorexplained in this answerとして)を使用し、これらの設定を行うことができます。

ObjectMapper om = new ObjectMapper(); 
om.registerModule(new JavaTimeModule()); 
om.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); 

この構成は、通常は十分ですが、念のために、同様falseSerializationFeature.WRITE_DATES_AS_TIMESTAMPSをも設定することができます。


あなたはまだjava.util.Dateで作業する必要がある場合は、/から、それに変換するために、APIを使用することができます。 Javaの8では、新しいDate.from方法があります:

// convert to java.util.Date 
public Date getStartAsJavaUtilDate() { 
    return Date.from(startDateTime.toInstant()); 
} 

はまた、ThreeTenバックポートで、org.threeten.bp.DateTimeUtilsクラスがあります:

// convert to java.util.Date 
DateTimeUtils.toDate(startDateTime.toInstant()); 

OffsetDateTimeDateバックを変換するには、しかし、それはよりトリッキーです。 Dateオブジェクトにはタイムゾーン情報がないため、元のオフセットは認識できません。あなたはDateInstantに変換した後、元のオフセットに変換することができ、その後

// keep the original offset 
ZoneOffset startDateOffset = startDateTime.getOffset(); 

// convert java.util.Date to original offset (Java 8) 
startDateTime = date.toInstant().atOffset(startDateOffset); 

// ThreeTen Backport 
startDateTime = DateTimeUtils.toInstant(date).atOffset(startDateOffset); 
+0

spring.jackson.time-zoneの設定はどうですか?注釈は私のために働きますが、春の設定は服用しません。 –

関連する問題