Reputation: 12415
I have a problem in parsing timestampls in Java.
I would expect to have both timestamps in the same timezone (CET).
SimpleDateFormat sdaf = new SimpleDateFormat ("dd.MM.yyyy HH:mm:ss");
String str = "30.03.2013 06:00:00";
sdaf.setTimeZone (TimeZone.getTimeZone ("CET"));
java.util.Date dat = sdaf.parse (str);
System.out.println (str + " = " + dat);
str = "31.03.2013 05:00:00";
sdaf.setTimeZone (TimeZone.getTimeZone ("CET"));
dat = sdaf.parse (str);
System.out.println (str + " = " + dat);
But that is not the case - see the output.
30.03.2013 06:00:00 = Sat Mar 30 06:00:00 CET 2013
31.03.2013 05:00:00 = Sun Mar 31 05:00:00 CEST 2013
EDIT:
If I change CET with GMT+1 I get this.
03.2013 06:00:00 = Sat Mar 30 06:00:00 CET 2013
31.03.2013 05:00:00 = Sun Mar 31 06:00:00 CEST 2013
Seems to be correct. But why is CET not working?
UTC+1 produces
30.03.2013 06:00:00 = Sat Mar 30 07:00:00 CET 2013
31.03.2013 05:00:00 = Sun Mar 31 07:00:00 CEST 2013
what is different to GMT+1 - ????
Upvotes: 3
Views: 4809
Reputation: 86379
AxelH’s answer is correct. Thus I don’t think you really want Central European (Standard) Time for your date-time on 31st March.
I should like to make three other points:
SimpleDateFormat
, TimeZone
and Date
and use java.time
, the modern Java date and time API, instead.So my code suggestion is:
ZoneId cetAllYear = ZoneId.of("Africa/Algiers");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.uuuu HH:mm:ss");
DateTimeFormatter demoFormatter
= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy", Locale.ROOT);
String str = "31.03.2013 05:00:00";
ZonedDateTime dateTime = LocalDateTime.parse(str, formatter).atZone(cetAllYear);
System.out.println (str + " = " + dateTime
+ " = " + dateTime.format(demoFormatter));
Output:
31.03.2013 05:00:00 = 2013-03-31T05:00+01:00[Africa/Algiers] = Sun Mar 31 05:00:00 CET 2013
The same is possible with Africa/Tunis time zone.
Avoid three letter time zone abbreviations. Central European Time is a common name for the standard time at offset +01:00 used 5 months of the year in a large number of European time zones. So in one way it’s only half a time zone, in another way it’s many, and you don’t know which one you get. And even less so when you give a date-time that falls in the summer time (DST time of the year). Very many three and four letter abbreviations are ambiguous. Instead give time zone as for example Europe/Rome or Africa/Tunis, as region/city.
Avoid SimpleDateFormat
and its outdated friends. That class is notoriously troublesome. java.time
is so much nicer to work with.
Links
java.time
.Upvotes: 2
Reputation: 14572
You can't get a CET
time zone for the 31.03.2013 05:00:00 because it was not on that timezone anymore. To understand, just check the name of both timezone
UTC+1
or GMT+1
)UTC+2
or GMT+2
)That's the Saving Daylight Time that occured during the 31.03.2013 at 02:00:00. So you can't get a CET
timezone for the second date since it is on the summer "time zone".
If you parse 31.03.2013 02:00:00
you will get
31.03.2013 02:00:00 = Sun Mar 31 03:00:00 CEST 2013
Because at 02:00:00 that day, the saving daylight time happened and it became 03:00:00.
You can check that using TimeZone.inDaylightTime(Date)
String str = "30.03.2013 06:00:00";
java.util.Date dat = sdaf.parse (str);
System.out.println (str + " = " + dat);
System.out.println("SDT : " + TimeZone.getTimeZone("CET").inDaylightTime(dat));
30.03.2013 06:00:00 = Sat Mar 30 06:00:00 CET 2013
SDT : false
str = "31.03.2013 02:00:00";
dat = sdaf.parse (str);
System.out.println (str + " = " + dat);
System.out.println("SDT : " + TimeZone.getTimeZone("CET").inDaylightTime(dat));
31.03.2013 02:00:00 = Sun Mar 31 03:00:00 CEST 2013
SDT : true
Since CET
is the same as UTC+1
or GMT+1
and CEST
become UTC+2
or GMT+2
, when you force the date to be on GMT+1
, you get the equivalent of the CET
but without taking into account the SDT parameter.
Note : This is one of the reason LocalDateTime
don't bother with TimeZone
for most of the processing.
Upvotes: 4
Reputation: 944
You can use Java 8 and it is more clear and simple than this one.
DateTimeFormatter parse = DateTimeFormatter.ofPattern("dd.MM.yyyy hh:mm:ss.XXX");
LocalDate localDate = LocalDate.of(2013,3,30);
LocalTime localTime = LocalTime.of(6,0);
LocalDateTime dateTime = LocalDateTime.of(localDate, localTime);
ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("CET"));
System.out.println(zonedDateTime.format(parse));
Output : 30.03.2013 06:00:00.+01:00
Upvotes: 1