Spring @DateTimeFormat conversion error with Daylight Saving Time

Sérgio Michels :

I'm using Spring MVC on a machine that has Daylight Saving Time configured (America/Sao_Paulo Time Zone). In my form class I used the annotation DateTimeFormat to configure the output of my Date:

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

While debugging I'm getting the date 16/10/2011 (dd/MM/yyyy) that's the start of the daylight time, but Spring converts it to 2011-10-15. Why?

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'

I see this question: @DateTimeFormat in Spring produces off-by-one day error

but Spring 3 uses Joda-Time and I have joda-time-2.0.jar in my classpath so I don't know why this occurs and how I can solve it.

[EDIT]

I've tested creating LocalData objets, and found something:

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

It seems that the first approach is thinking that the time is in UTC, because debugging I can see that Joda use the method convertUTCToLocal of the class DateTimeZone.

Maybe this is the default of the Spring too, he expect's one date in UTC too and i am passing the BRT Date.

So I think my solution is change the objects to LocalDate and use the second way to create the instance of this object.

Andreas Wederbrand :

This might answer parts of your question.

When ever you have a java.util.Data object that will be printed in your systems time zone inside toString. So, if you set a date that is in UTC 2011-10-16 00:00:00 that's going to be converted into a UTC timestamp internally in the Date. toString will print that timestamp in your local timezone and that's going to be a couple of hours after UTC (since Sao Paolo is west of London) so roughly 2011-10-15 22:00:00. That is what you'll see on break points and debug prints. The Data might still be correct internally though.

If found that the only real way of printing Dates is through SimpleDateFormat like this:

    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
    }

Now the print will look very confusing

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

But lets walk through it.

  1. First, my SimpleDateFormat gets a format and I set it to assume all text in and out is in UTC timezone.
  2. When I parse the date 2011-10-16 00:00:00 that will be interpretted as UTC but when I print it java uses my locale (CET) to print this as 2011-10-16 01:00:00, that is also what I would see on a break point
  3. When I create a new Date() that Date will be in my locale and when I print it it will show 15:47 (my current time) but when I format it with my timezone aware SimpleDateFormat it will show the time in UTC.

That said, java and dates will confuse you until you pull your hair out :)

Hope this helps some.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related