2011-11-04 11 views
5

Używam Spring MVC na komputerze, który ma skonfigurowany czas letni (strefa czasowa America/Sao_Paulo). W moim klasy formularza użyłem DateTimeFormat adnotacji do skonfigurowania wyjścia mojego Data:Konwersja Spring @DateTimeFormat z czasem letnim

public class JustificativaOcorForm { 
    ... 
    @NotNull 
    @DateTimeFormat(pattern="yyyy-MM-dd") 
    private Date dataMarcacao; 
    ... 
} 

Podczas debugowania Dostaję datę 16/10/2011 (dd/mm/rrrr), który jest początkiem światła dziennego czas, ale Spring zamienia go na 2011-10-15. Czemu?

2011-11-04 16:35:31,965 [http-8080-Processor25] DEBUG org.springframework.core.convert.support.GenericConversionService - Converting value Sun Oct 16 00:00:00 BRST 2011 of [TypeDescriptor @javax.validation.constraints.NotNull @org.springframework.format.annotation.DateTimeFormat java.util.Date] to [TypeDescriptor java.lang.Long] 
2011-11-04 16:35:31,965 [http-8080-Processor25] DEBUG org.springframework.core.convert.support.GenericConversionService - Converted to 1318730400000 
2011-11-04 16:35:32,010 [http-8080-Processor25] DEBUG org.springframework.core.convert.support.GenericConversionService - Converted to '2011-10-15' 

widzę to pytanie: @DateTimeFormat in Spring produces off-by-one day error

ale Wiosna 3 wykorzystuje Joda-Time i mam Joda-Time-2.0.jar w mojej ścieżce klasy więc nie wiem, dlaczego tak się dzieje i jak mogę rozwiązać.

[EDIT]

Przetestowałem tworzenia objets LocalData i znalazł coś:

LocalDate ld = new LocalDate(new SimpleDateFormat("dd/MM/yyyy").parse("16/10/2011").getTime()); 
System.out.println(new SimpleDateFormat("dd/MM/yyyy HH:mm:ss Z z").format(ld.toDate()) ); 
//prints 15/10/2011 00:00:00 -0200 BRST 

LocalDate ld2 = new LocalDate(2011,10,16); 
System.out.println(new SimpleDateFormat("dd/MM/yyyy HH:mm:ss Z z").format(ld2.toDate()) ); 
//prints 16/10/2011 00:00:00 -0200 BRST 

Wydaje się, że pierwsze podejście jest myślenie, że czas jest w UTC, ponieważ debugowania widać, że Joda używa metody convertUTCToLocal klasy DateTimeZone.

Może to również jest domyślne w Spring, on też spodziewa się jednej daty w UTC i przejdę do daty BRT.

Myślę, że moim rozwiązaniem jest zmiana obiektów na LocalDate i użycie drugiej metody tworzenia instancji tego obiektu.

+0

Nie jest jasne - czy konwertujesz * na * ciąg znaków, czy * na * ciąg znaków? Ponadto, jeśli ma to być tylko data, lepiej byłoby użyć typu 'LocalDate' firmy Joda. –

+0

@ JonSkeet to data na ciąg. Mogę ustawić LocalDate z @DateTimeFormat? –

+0

Z pewnością bym tego oczekiwał. Zauważ, że twoja wartość "Date" wydaje się być północą * BRST * 16 października ... czy to celowe? Wprawdzie to dziwne, że jest sformatowany jako 15 października ... ale ogólnie lepiej byłoby całkowicie unikać stref czasowych, jeśli używasz dat :) –

Odpowiedz

5

To może odpowiedzieć na części twojego pytania.

Kiedykolwiek masz obiekt java.util.Data, który będzie drukowany w strefie czasowej twojego systemu wewnątrz toString. Tak więc, jeśli ustawisz datę, która jest w UTC 2011-10-16 00:00:00, to zostanie ona przekształcona w sygnaturę czasową UTC wewnętrznie w Data. toString wypisze, że znacznik czasu w lokalnej strefy czasowej i że będzie to kilka godzin po UTC (od Sao Paolo jest na zachód od Londynu), więc z grubsza 2011-10-15 22:00:00. To właśnie zobaczysz na break pointach i wydrukach debugowania. Dane mogą jednak nadal być poprawne wewnętrznie.

Jeśli okazało się, że jedynym realnym sposobem drukowania dat jest przez SimpleDateFormat tak:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
    try { 
     Date dateInUTC = dateFormat.parse("2011-10-16 00:00:00"); 
     Date currentDate = new Date(); 
     String stringInUTC = dateFormat.format(currentDate); 
     System.out.println(dateInUTC); 
     System.out.println(currentDate); 
     System.out.println(stringInUTC); 
    } 
    catch (ParseException e) { 
     // not too worry, I wrote a nice date 
    } 

Teraz wydruku będzie wyglądać bardzo mylące

Sun Oct 16 01:00:00 CET 2011 
Thu Nov 10 15:47:46 CET 2011 
2011-11-10 14:47:46 

Ale pozwala przejść przez niego.

  1. Po pierwsze, mój SimpleDateFormat otrzymuje format i ustawiam go tak, aby zakładał, że cały tekst jest w strefie czasowej UTC.
  2. Kiedy przeanalizuję datę 2011-10-16 00:00:00, która zostanie zinterpretowana jako UTC, ale gdy ją wydrukuję, java użyje mojego ustawienia narodowego (CET), aby wydrukować to jako 2011-10-16 01:00:00 , który jest również to, co widzę na punkt przerwania
  3. kiedy tworzę nową datę(), która data będzie w mojej lokalizacji i kiedy go wydrukować pokaże 15:47 (mój aktualny czas), ale kiedy Format to z moją strefą czasową świadomą SimpleDateFormat pokaże czas w UTC.

Powiedział, java i terminy będą mylić aż wyciągnąć włosy :)

Hope this helps niektórych.

+0

Bardzo interesujące wytłumaczenie! Prawdopodobnie Wiosna wymusza pewne strefy czasowe.Będę se, jeśli mogę użyć SimpleDateFormat jako conversor zamiast GenericConversionService –

+0

Cieszę się, że to pomaga. Myślę, że właśnie tego szukasz http://static.springsource.org/spring/docs/3.0.6.RELEASE/javadoc-api/org/springframework/beans/propertyeditors/ CustomDateEditor.html –

Powiązane problemy