2017-10-16 285 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 example。](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;

看來做你想做的(調整0:00至1:00),你需要實現一個validator如下內容:

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

好的catch,@ OleV.V. – hd1

0

如果你想使用的是Java 8類的一部分和新(java 8以後)「java.time」框架的一部分DateTimeFormat您可能需要使用Java 8 Date類:

DATE:
java.time.LocalDate

時間:
java.time.LocalTime,java.time.OffsetTime

TIMESTAMP:
java.time.Instant,java.time.LocalDateTime,java.time。 OffsetDateTime和java.time.ZonedDateTime

另外,哪個ORM與您的Spring框架一起使用?春天的數據,休眠或其他什麼?如果您使用休眠,請參考休眠用戶指南:Mapping Date/Time Values

0

根據您在數據庫中存儲日期的方式以及服務器時區 ,解決方案是在Spring初始化時將您的默認時區設置爲UTC,下面的代碼:

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

1

對於我來說,你不應該與系統的語言環境搞糟直接。那真正的問題是你的問題。

我的意思是你沒有提供時區,所以你正在使用的服務器之一。在這臺服務器上,它的配置將是今天/日期。在另一臺服務器上,會有另一天/日期。

請確保您使用UTC(無需全天節電和全部)或客戶端在輸入中提供的顯式區域設置,使用本地日期進行存儲......可以保持它的樣子,當您需要時比較日期,將其轉換爲UTC。這樣問題就會消失。

快速修復是確保您的服務器使用UTC,但從長遠來看,您應該始終控制您使用的語言環境,因此提供的日期必須是UTC或它是本地日期,而另一個字段提供時區。

+0

我有一個默認配置的應用程序「pt_BR」的區域設置,所以它會一直使用這個日期 – Thiesen

0

這應該是非常簡單的。

這裏的問題是,您正在爲日期對象傳遞一個字符串值。這裏是有問題的註釋的文檔:

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"))); 

希望幫助!