perencia
perencia

Reputation: 1542

Java Date + Calendar giving different results than expected

I have the following code:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalendarTest {

    public static void main(String[] args) {

        try {

            Calendar calendar = Calendar.getInstance();

            Date _date = new SimpleDateFormat("ddMMyyyy").parse("13102014");
            Date _time = new SimpleDateFormat("hhmmss").parse("201100");

            calendar.setTimeInMillis(_date.getTime() + _time.getTime());

            System.out.println(calendar.getTime()); // NOK 1 hour less

        } catch (ParseException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
}

Why does it produce:

Mon Oct 13 19:11:00 CEST 2014

Instead of:

Mon Oct 13 20:11:00 CEST 2014

Upvotes: 0

Views: 529

Answers (4)

Affe
Affe

Reputation: 47954

When you parse only the time on a separate line from the date, it treats it as though that time occurs on Jan 1st 1970. Which is in the winter when you are on standard time. So when you combine the two together you get a value that's in standard time, one hour behind the current clock-on-the-wall time which is in Daylight time.

Upvotes: 1

duffymo
duffymo

Reputation: 308733

I would say that it's possible to produce the desired output with a simple change. No JODA or Java 8 needed. I don't understand why you wrote it the way you did.

package cruft;

/**
 * CalendarTest description here
 * @author Michael
 * @link  https://stackoverflow.com/questions/26348140/java-date-calendar-giving-different-results-as-expected
 * @since 10/13/2014 4:16 PM
 */
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalendarTest {

    public static void main(String[] args) {

        try {

            Calendar calendar = Calendar.getInstance();

            Date _date = new SimpleDateFormat("ddMMyyyy hhmmss").parse("13102014 201100");

            calendar.setTimeInMillis(_date.getTime());

            System.out.println(calendar.getTime()); 

        } catch (ParseException e1) {
            e1.printStackTrace();
        }
    }
}

Here's the output I get:

"C:\Program Files\Java\jdk1.7.0_45\bin\java" -Didea.launcher.port=7536 "
Mon Oct 13 20:11:00 EDT 2014

Process finished with exit code 0

Upvotes: 1

Basil Bourque
Basil Bourque

Reputation: 338181

Joda-Time

The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. Use a competent date-time library instead. In Java that means either:

  • Joda-Time
    The venerable library used by many people for many years as a replacement for j.u.Date/Calendar.
  • java.time
    Bundled with Java 8, inspired by Joda-Time, defined by JSR-310, described in The Tutorial)

In Joda-Time, a DateTime object knows its own assigned time zone (unlike j.u.Date).

That string format in your Question is annoyingly bad. If possible, replace with ISO 8601 standard strings. The standard strings are much more readable and intuitive. Furthermore, both Joda-Time and java.time parse and generate standard strings by default.

Example code using Joda-Time 2.5. We do not know your time zone, so I am arbitrarily choosing Berlin. I assume your input string represents a moment in that time zone, though your Question is ambiguous.

Parse input string.

String input = "13102014201100";
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "ddMMyyyyHHmmss" );
DateTimeFormatter formatterBerlin = formatter.withZone( timeZone );
DateTime dateTimeBerlin = formatterBerlin.parseDateTime( input );

Adjust to another time zone. In this case, UTC.

DateTime dateTimeUtc = dateTimeBerlin.withZone( DateTimeZone.UTC );

Dump to console.

System.out.println( "input: " + input );
System.out.println( "dateTimeBerlin: " + dateTimeBerlin );
System.out.println( "dateTimeUtc: " + dateTimeUtc );

When run.

input: 13102014201100
dateTimeBerlin: 2014-10-13T20:11:00.000+02:00
dateTimeUtc: 2014-10-13T18:11:00.000Z

Upvotes: 0

Basil Bourque
Basil Bourque

Reputation: 338181

UTC versus DST

Because java.util.Date works in UTC. But its toString method confusingly applies your JVM’s current default time zone when generating a String representation of the date-time value.

I imagine your JVM’s current default time zone is in Daylight Saving Time (DST), thus the hour adjustment.

24-Hour Time

Also, your hour-of-day code should be HH for 24-hour time, not hh for 12-hour time.

Upvotes: 4

Related Questions