2017-10-16 14 views
7

@DateTimeFormatアノテーションを使用して実際には存在しない日付の変換に問題があります。例えば@DateTimeFormat変換時に夏時間エラーが発生する

、私は日付15/10/2017を設定し、私のエンティティ内の注釈は以下の通りであると:

@Column(nullable = false) 
@NotNull 
@DateTimeFormat(pattern = "dd/MM/yyyy") 
private Date dataVisita; 

私はエラーが表示されます。

Failed To Convert Property Value Of Type Java.Lang.String To Required Type Java.Util.Date For Property DataVisita; 
Nested Exception Is Org.Springframework.Core.Convert.ConversionFailedException: 
    Failed To Convert From Type Java.Lang.String To Type @Javax.Persistence.Column @Javax.Validation.Constraints.NotNull @Org.Springframework.Format.Annotation.DateTimeFormat Java.Util.Date For Value 15/10/2017; 
Nested Exception Is Java.Lang.IllegalArgumentException: 
    Cannot Parse "15/10/2017": Illegal Instant Due To Time Zone Offset Transition (America/Sao_Paulo) 

私は理解していることエラーは私に、15/10/2017 00:00:00という日付は実際には存在しませんが、私は15/10/2017 01:00:00に変換して、このように問題を無視し、通信相手の日付を見つけることを望んでいます。

@DateTimeFormatアノテーションをオーバーライドする方法や、フォーマッタを寛容にする方法がありますか?

+1

「あなたが言うことを意味して、何を言っているのか」現在、日付と時刻を表すオブジェクトに日付を入れようとしています。あなたはLocalDateを使うことができますか?またはDateを使っていませんか? – mpkorstanje

+0

カスタムデシリアライザを作成できます。 AFAIRそれはボンネットの下でジャクソンを使用します。 'JsonDeserialize'アノテーションが役立つはずです。 [Jackson-Deserializationの例](http://www.baeldung.com/jackson-deserialization) –

+0

'@DateTimeFormat(iso = ISO.DATE_TIME)'を使用しようとすると、文字列の時間が無視されません –

答えて

3

これを試してみてください:

@Column(nullable = false)

@NotNull

@DateTimeFormat(pattern = "dd/MM/yyyy HH:mm:ss")

private Date dataVisita;

あなたが、あなたは次のようにvalidatorを実装する必要があります(1時まで午前0時を調整)やりたいようだ:

public class PersonValidator implements Validator { 

    /** 
    * This Validator validates *just* Person instances 
    */ 
    public boolean supports(Class clazz) { 
     return Date.class.equals(clazz); 
    } 

    public void validate(Object obj, Errors e) { 
     String dateString = (String) obj; 
     DateTimeFormatter fmt = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss"); 
     DateTime ourDate = null; 
     try { 
      fmt.parseDateTime(dateString); 
     } catch (IllegalArgumentException e) { 
      // massage your hour here 
     } finally { 
      ourDate = fmt.parseDateTime(dateString); 
     } 
    } 
} 
+0

良いキャッチ@ OleV.V. – hd1

0

DateTimeFormatをJava 8クラス、新しい(よくJava 8以降) "java.time"フレームワークの一部として使用する場合は、おそらくJava 8の日付クラスを使用する必要があります。

日付:
java.time.LocalDate

TIME:
java.time.LocalTime、java.time.OffsetTime

TIMESTAMP:
java.time.Instant、java.time.LocalDateTime、java.time。 OffsetDateTimeとjava.time.ZonedDateTime

また、どのORMでSpringフレームワークを使用していますか?春のデータ、休止状態または何か他の?あなたがDBにあなたの日付を格納する方法に応じてMapping Date/Time Values

0

、およびサーバーのタイムゾーンは、 ソリューションを使用して、春の初期化にUTCにあなたのデフォルトのタイムゾーンを設定するには、次のようになります。あなたが休止状態を使用する場合は、Hibernateのユーザーズマニュアルを参照してください次のコード:私にとって

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

1

は、あなたは、システムのロケールと直接台無しべきではありません。あなたの問題は本当にそれです。

つまり、サーバーの1つを使用しているため、タイムゾーンを指定していないということです。このサーバーの設定では、この日/日付になります。別のサーバーでは、別の日/日付になります。

クライアントが入力で指定した明示的なロケールまたはUTCのいずれかで作業していることを確認してください。ローカル日付を使用して保存してください。日付を比較するには、それをUTCに変換します。このようにして問題は消滅します。

サーバーがUTCを使用するようにするには、すばやい修正が必要ですが、長期的には、使用するロケールを常に制御する必要があります。したがって、指定された日付はUTCでなければならず、ローカル日付でなければならず、 。

+0

私は、アプリケーション "pt_BR"のデフォルトロケールを設定していますので、常にこれを日付に使用します – Thiesen

0

これは本当に簡単です。

ここで問題となるのは、DateオブジェクトにString値を渡していることです。ここで問題になっている注釈のドキュメントは次のとおりです。単純にここに置か

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/format/annotation/DateTimeFormat.html

が必要なタイプです:java.util.Date、java.util.Calendarの、java.lang.Longの、ジョダタイム値の型

非常に素朴な方法:

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); 
Date destnationDateToBeSaved = sdf.parse("15/10/2017"); 

推奨方法:

使用:

@DateTimeFormat(iso = ISO.DATE_TIME) 
private ZonedDateTime zonedDateTime; 

// 'yyyy-MMM-dd HH:mm:ss' pattern or if preferred ISO 
ZonedDateTime destnationDateToBeSaved= ZonedDateTime.parse("2017-Oct-15 23:35:05", DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss").withZone(ZoneId.of("UTC"))); 

役に立てば幸い!