2017-10-16 13 views
7

Mam problem z przekształceniem daty, która faktycznie nie istnieje z użyciem adnotacji @DateTimeFormat.@DateTimeFormat z błędem czasu letniego podczas konwertowania

Na przykład, kiedy ustawić datę 15/10/2017, z dopiskiem w moim podmiot jest w następujący sposób:

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

otrzymuję błąd:

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) 

Rozumiem, że error informuje mnie, że data 15/10/2017 00:00:00 faktycznie nie istnieje, ale chcę przekonwertować na 15/10/2017 01:00:00, ignorując w ten sposób problem i znajdując odpowiednią datę.

Czy istnieje sposób, aby zastąpić adnotację @DateTimeFormat lub sposób na sformułowanie programu formatującego jako łagodnego?

+1

"Oznacza to, co mówisz i mówisz, co masz na myśli" Obecnie próbujesz umieścić datę w obiekcie, który reprezentuje datę i godzinę. Czy możesz użyć LocalDate lub utknąłeś w Date? – mpkorstanje

+0

Można utworzyć niestandardowy deserializator. AFAIR wykorzystuje Jacksona pod maską. Powinna pomóc adnotacja 'JsonDeserialize'. [Przykład Jackson-Deserialization.] (Http://www.baeldung.com/jackson-deserialization) –

+0

Spróbuj użyć '@DateTimeFormat (iso = ISO.DATE_TIME)', to nie będzie ignorować czasu w łańcuchu –

Odpowiedz

3

Spróbuj tego:

@Column(nullable = false)

@NotNull

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

private Date dataVisita;

Wydaje się robić to, co chcesz (0:00 do 1:00 wyregulować), trzeba wdrożyć validator następująco:

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

Dobre złapanie, @ OleV.V. – hd1

0

Jeśli chcesz używać klasy DateTimeFormat, która jest klasą Java 8 i częścią nowego (od czasu instalacji w języku Java 8) struktury "java.time", prawdopodobnie musisz używać klas dat Java 8:

DATA:
java.time.LocalDate

TIME:
java.time.LocalTime, java.time.OffsetTime

TIMESTAMP:
java.time.Instant, java.time.LocalDateTime, java.time. OffsetDateTime i java.time.ZonedDateTime

Ponadto, jakiego ORMu używasz w swojej strukturze Spring? Wiosenne dane, hibernacja czy coś innego? Jeśli używasz hibernacji, a następnie skonsultować się z instrukcji użytkownika hibernacji: Mapping Date/Time Values

0

zależności od sposobu przechowywania dat w DB, a strefa czasowa serwera rozwiązaniem byłoby, aby ustawić domyślną strefę czasową UTC na wiosennym inicjalizacji, używając Poniższy kod:

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

1

Dla mnie, nie powinien zepsuć bezpośrednio z ustawień narodowych systemu. To naprawdę jest twój problem.

Mam na myśli, że nie podałeś strefy czasowej, więc używasz jednego z serwerów. Na tym serwerze z jego konfiguracją będzie to dzień/data. Na innym serwerze byłby to kolejny dzień/data.

Upewnij się, że pracujesz w UTC (bez zapisywania światła dziennego i wszystkich) lub w jawnych ustawieniach narodowych wprowadzonych przez klienta przy wprowadzaniu danych, zapisuj datę lokalną ... Zachowaj to i kiedy potrzebujesz porównać daty, przekonwertować je na UTC. W ten sposób problem zniknie.

Szybką poprawką jest zapewnienie, że serwer używa UTC, ale na dłuższą metę należy zawsze kontrolować, z jakich ustawień regionalnych korzystasz, więc podana data musi być czasem UTC lub jest datą lokalną, a inne pole określa strefę czasową .

+0

Mam domyślnie skonfigurowane ustawienia narodowe dla aplikacji "pt_BR", więc zawsze będzie to używane dla dat – Thiesen

0

To powinno być naprawdę proste.

Problem polega na tym, że podajesz wartość ciągu dla obiektu daty. Oto dokumentacji adnotacji w pytaniu:

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

prostu umieścić tu są rodzaje wymagane: typy wartości java.util.Date, java.util.Calendar, java.lang.Long, Joda-czasowe

bardzo naiwny sposób:

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

Zalecany sposób:

Zastosowanie:

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

i

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

nadzieję, że pomoże!

Powiązane problemy