Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java SimpleDateFormat interpret parse-string as UTC

Tags:

java

date

my timezone is GMT+1.

so a "Date"-object with "22.09.1985 00:00UTC" prints "Sun Sep 22 01:00:00 CEST 1985" on the tostring function.

Now i'm trying to create this date by parsing "22/09/1985" with simpleDateFormat

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getDefault());
Date d = sdf.parse("22/09/1985");
    => Sun Sep 22 00:00:00 CEST 1985

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date d = sdf.parse("22/09/1985");
    => Sun Sep 22 02:00:00 CEST 1985

how can i configure simpledateformat that it creates an Date which prints "Sun Sep 22 01:00:00 CEST 1985" with input string "22/09/1985"?

like image 791
wutzebaer Avatar asked Feb 21 '14 16:02

wutzebaer


2 Answers

My assumption was wrong,

22.09.1985 00:00UTC is actually 22.09.1985 02:00CET

so

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date d = sdf.parse("22/09/1985");

is exactly what i wanted, the date i compared it with was wrong.

like image 176
wutzebaer Avatar answered Sep 28 '22 00:09

wutzebaer


Avoid java.util.Date & Calendar

You’ve found one of the many reasons to avoid using java.util.Date & .Calendar. They are notoriously troublesome. Either use Joda-Time or, in Java 8, the new java.time package which is inspired by Joda-Time and defined by JSR 310.

Search StackOverflow for "joda date" to find many examples.

Time Zone

You said:

my timezone is GMT+1.

Incorrect, your local offset from UTC/GMT is +01. That is not your time zone. A time zone is an offset plus rules about Daylight Saving Time (DST) and other anomalies.

And that offset should have two digits: +01 (or +01:00) rather than +1, according to the ISO 8601 standard.

Avoid the 3 or 4 letter codes such as CET. They are neither standardized nor unique. Use proper time zone names.

Generally speaking, you should specify a time zone in all your date-time work rather than rely on the current JVM's default.

In both Joda-Time and java.time, a date-time object truly knows its assigned time zone. A java.util.Date has no time zone, but seems to because its toString applies the default time zone when creating a String representation, as you sadly learned the hard way.

Example Code

Some code using Joda-Time 2.3.

String input = "22/09/1985";

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Amsterdam" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy" );
DateTime dateTime = formatter.withZone( timeZone ).parseDateTime( input );
DateTime dateTimeUtcGmt = dateTime.withZone( DateTimeZone.UTC );
DateTime dateTimeIndia = dateTime.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
String outputMontreal = DateTimeFormat.forStyle( "FF" ).withZone( DateTimeZone.forID( "America/Montreal" ) ).withLocale( Locale.CANADA_FRENCH ).print( dateTime );
// All of the above date-time represent the very same moment in the timeline of the Universe.

Dump to console…

System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtcGmt: " + dateTimeUtcGmt );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "outputMontreal: " + outputMontreal );

When run…

dateTime: 1985-09-22T00:00:00.000+02:00
dateTimeUtcGmt: 1985-09-21T22:00:00.000Z
dateTimeIndia: 1985-09-22T03:30:00.000+05:30
outputMontreal: samedi 21 septembre 1985 18 h 00 EDT
like image 27
Basil Bourque Avatar answered Sep 27 '22 23:09

Basil Bourque