SimpleDateFormat - Timezone not correct - java

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 - ????

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
CET : Central European Time (UTC+1 or GMT+1)
CEST : Central European Summer Time (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.

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:
You should never rely on any three or four letter time zone abbreviation, like CET.
If you really want Central European Time, it is possible since two African countries use CET all year, Algeria and Tunesia.
Avoid the outdated 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
Oracle tutorial: Date Time explaining how to use java.time.
Central European Time on timeanddate.com.

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

Related

Convert String to LocalDateTime in Java

I have this String
Fri, 07 Aug 2020 18:00:00 +0000
And I need to convert it to a LocalDateTime
I tryed several ways:
create a DateTimeFormatter and parse the String
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss", Locale.getDefault());
LocalDateTime parsedDate = LocalDateTime.parse(publishedString, formatter);
Convert it to a Date with a SimpleDateFormat and then convert the resultDate to a LocalDateTime
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
SimpleDateFormat dateFormatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z");
Date date = dateFormatter.parse(publishedString);
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
both solution gives me the same exception:
java.time.format.DateTimeParseException: Text 'Fri, 07 Aug 2020 18:00:00 +0000' could not be parsed
at index 0 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
How can I convert that String?
I'd say use Locale.ROOT and don't forget the Z in the DateTimeFormatter class
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss Z", Locale.ROOT);
LocalDateTime parsedDate = LocalDateTime.parse(dateString, formatter);
tl;dr
OffsetDateTime.parse(
"Fri, 07 Aug 2020 18:00:00 +0000" ,
DateTimeFormatter.RFC_1123_DATE_TIME
)
See this code run live at IdeOne.com.
LocalDateTime is the wrong class
Your input string contains +0000 which indicates an offset-from-UTC.
So you should not be using LocalDateTime. That class purposely lacks any concept of time zone or offset. With LocalDateTime, your string Fri, 07 Aug 2020 18:00:00 +0000 will become 6M on August 7th 2020, but we won't know if that is 6 PM in Tokyo Japan, 6 PM in Toulouse France, or 6 PM in Toledo Ohio US — all different moments several hours apart.
OffsetDateTime
Instead, this value should be parsed as OffsetDateTime.
Parsing
Your input's format is that of RFC 1123. That particular format is predefined in java.time.
String input = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter f = DateTimeFormatter.RFC_1123_DATE_TIME;
OffsetDateTime odt = OffsetDateTime.parse( input , f );
odt.toString(): 2020-08-07T18:00Z
I understand that you need a LocalDateTime for an API that due to a design problem beyond your control is trying to use LocalDateTime for a point in time.
If an external contract dictates in which time zone or at which UTC offset the LocalDateTime is to be understood, LocalDateTime can be made to work, at least for 99.977 % of cases. You will still have a programming error waiting to happen on the day when some colleague programmer does not read the contract, a problem that we cannot solve in the code, only try to mitigate through good commenting.
If for example the contract says UTC, then we need to make sure we convert the time to UTC. And we need the offset from the string for doing so.
ZoneOffset contractualOffset = ZoneOffset.UTC;
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.withOffsetSameInstant(contractualOffset)
.toLocalDateTime();
System.out.println(convertedDateTime);
Output:
2020-08-07T18:00
If the offset in the string is required to be 0 already, you need to validate that it is, or errors will go unnoticed and users will get wrong results. For example:
OffsetDateTime parsedOdt = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME);
if (! parsedOdt.getOffset().equals(contractualOffset)) {
throw new IllegalStateException("Offset must be " + contractualOffset
+ ", was " + parsedOdt.getOffset());
}
LocalDateTime convertedDateTime = parsedOdt.toLocalDateTime();
If the contract mentions some time zone, convert to that time zone. I am taking Australia/Victoria as an example.
ZoneId contractualZone = ZoneId.of("Australia/Victoria");
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.atZoneSameInstant(contractualZone)
.toLocalDateTime();
System.out.println(convertedDateTime);
2020-08-08T04:00
You will get an ambiguous result at time anomalies where the clock is turned backward, for example at the fall back when summer time (DST) ends.
What went wrong in your code?
The cause of your exception is explained here:
new SimpleDateFormat(“hh:mm a”, Locale.getDefault()).parse(“04:30 PM”) giving Unparseable exception
java DateTimeFormatterBuilder fails on testtime

Get same date in different timezone

I have a epochmilli sec time.
Created a date object from this epoch time.
Date date = new Date(epochMilli);
Suppose date is "23 Nov 2019 00:00:00"
Now, I just want to get this same date in different timezones like :]
Japan time : 23 Nov 2019 00:00:00
US time : 23 Nov 2019 00:00:00
I am currently using LocalDateTime or ZonedDateTime.
But when I am converting into different zone, time also changes. But I don't want this time to change.
Thanks in Advance.
Unfortunately, you didn't show us how you used ZonedDateTime, so the following examples may cover more than you just wanted by showing how to parse millis, convert the resulting date time from one zone to others and how to parse a date time using different zones:
public static void main(String[] args) {
long epochMillis = 1574208000000L;
// define a formatter to be used
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss",
Locale.ENGLISH);
// create an instant from the milliseconds
Instant instant = Instant.ofEpochMilli(epochMillis);
// and create some example time zones for later use
ZoneId utc = ZoneId.of("UTC");
ZoneId tokyo = ZoneId.of("Asia/Tokyo");
ZoneId losAngeles = ZoneId.of("America/Los_Angeles");
ZoneId chicago = ZoneId.of("America/Chicago");
/*
* Part 1: Getting the date time converted to different time zones
*/
// use the instant to create a ZonedDateTime at a specific time zone, here: UTC
ZonedDateTime utcZdt = instant.atZone(utc);
// then take the UTC-ZonedDateTime as base for conversion to other time zones
ZonedDateTime asiaTokyoConvertedfromUtc = utcZdt.withZoneSameInstant(tokyo);
ZonedDateTime americaLosAngelesConvertedfromUtc = utcZdt.withZoneSameInstant(losAngeles);
ZonedDateTime americaChicagoConvertedfromUtc = utcZdt.withZoneSameInstant(chicago);
// print the results
System.out.println("#### 1574208000000L at UTC, converted to other zones ####");
System.out.println("UTC time zone:\t\t\t\t" + utcZdt.format(dtf));
System.out.println("JST (Japan/Tokyo) time zone:\t\t"
+ asiaTokyoConvertedfromUtc.format(dtf));
System.out.println("PST (USA/Los Angeles) time zone:\t"
+ americaLosAngelesConvertedfromUtc.format(dtf));
System.out.println("CST (USA/Chicago) time zone:\t\t"
+ americaChicagoConvertedfromUtc.format(dtf));
System.out.println();
/*
* Part 2: Getting the date time in different time zones
*/
// use the instant to create a ZonedDateTime at Asia/Tokyo
ZonedDateTime asiaTokyoFromMillis = instant.atZone(tokyo);
// use the instant to create a ZonedDateTime at America/Los Angeles
ZonedDateTime americaLosAngelesFromMillis = instant.atZone(losAngeles);
// use the instant to create a ZonedDateTime at America/Chicago
ZonedDateTime americaChicagoFromMillis = instant.atZone(chicago);
// print the (expected) results, same as converted date times...
System.out.println("#### 1574208000000L at different zones ####");
System.out.println("UTC time zone:\t\t\t\t" + utcZdt.format(dtf));
System.out.println("JST (Asia/Tokyo) time zone:\t\t"
+ asiaTokyoFromMillis.format(dtf));
System.out.println("PST (USA/Los Angeles) time zone:\t"
+ americaLosAngelesFromMillis.format(dtf));
System.out.println("CST (USA/Chicago) time zone:\t\t"
+ americaChicagoFromMillis.format(dtf));
System.out.println();
/*
* Part 3: How to parse the date time instead of millis
*/
// provide a parseable date time String
String dateTime = "23 Nov 2019 00:00:00";
// parse it in each desired time zone
ZonedDateTime utc23Nov2019 = LocalDateTime.parse(dateTime, dtf).atZone(utc);
ZonedDateTime asiaTokyo23Nov2019 = LocalDateTime.parse(dateTime, dtf)
.atZone(tokyo);
ZonedDateTime americaChicago23Nov2019 = LocalDateTime.parse(dateTime, dtf)
.atZone(losAngeles);
ZonedDateTime americaLosAngeles23Nov2019 = LocalDateTime.parse(dateTime, dtf)
.atZone(chicago);
// print the results, now you have the 23. Nov 2019 at 00:00:00 at each time zone
System.out.println("#### \"23 Nov 2019 00:00:00\" at different zones ####");
System.out.println("UTC time zone:\t\t\t\t" + utc23Nov2019.format(dtf));
System.out.println("JST (Asia/Tokyo) time zone:\t\t"
+ asiaTokyo23Nov2019.format(dtf));
System.out.println("PST (USA/Los Angeles) time zone:\t"
+ americaChicago23Nov2019.format(dtf));
System.out.println("CST (USA/Chicago) time zone:\t\t"
+ americaLosAngeles23Nov2019.format(dtf));
}
The output of this is
#### 1574208000000L at UTC, converted to other zones ####
UTC time zone: 20 Nov 2019 00:00:00
JST (Japan/Tokyo) time zone: 20 Nov 2019 09:00:00
PST (USA/Los Angeles) time zone: 19 Nov 2019 16:00:00
CST (USA/Chicago) time zone: 19 Nov 2019 18:00:00
#### 1574208000000L at different zones ####
UTC time zone: 20 Nov 2019 00:00:00
JST (Asia/Tokyo) time zone: 20 Nov 2019 09:00:00
PST (USA/Los Angeles) time zone: 19 Nov 2019 16:00:00
CST (USA/Chicago) time zone: 19 Nov 2019 18:00:00
#### "23 Nov 2019 00:00:00" at different zones ####
UTC time zone: 23 Nov 2019 00:00:00
JST (Asia/Tokyo) time zone: 23 Nov 2019 00:00:00
PST (USA/Los Angeles) time zone: 23 Nov 2019 00:00:00
CST (USA/Chicago) time zone: 23 Nov 2019 00:00:00
The legacy java.util.Date is not time-zone-aware. It is basically a point in time measured in milliseconds since 1970-1-1 0:00. Nothing else.
When a date is print, it is formatted using your system's default locale and time zone. In order to get a java.util.Date object formatted for a different time zone you have to configure your DateFormat accordingly.
Date pointInTime = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance();
dateFormat.setTimeZone(TimeZone.getTimeZone("PST"));
System.out.println(dateFormat.format(pointInTime));
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormat.format(pointInTime));
With the newer LocalDate API, things are different. The previous answer gives a rich example.

Convert String in EST to Date in PST

I tried the below approach and searched in Web to find the solution for this but no luck : looking for the solution for converting a String in IST to PST:
String string = new Date().toString();
System.out.println(string);
SimpleDateFormat dt = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
dt.setTimeZone(TimeZone.getTimeZone("PST"));
Date D = dt.parse(string);
System.out.println(""+ D);
Even when I set time zone as PST, I am seeing out put in IST
here is the out put:
Tue Apr 18 18:58:09 IST 2017
Tue Apr 18 18:58:09 IST 2017
I tried another Option here I am seeing even it is showing the time in PST but I see below output it is a bit confusing:
public static Date convertFromOneTimeZoneToOhter(Date dt,String from,String to ) {
TimeZone fromTimezone =TimeZone.getTimeZone(from);//get Timezone object
TimeZone toTimezone=TimeZone.getTimeZone(to);
long fromOffset = fromTimezone.getOffset(dt.getTime());//get offset
long toOffset = toTimezone.getOffset(dt.getTime());
//calculate offset difference and calculate the actual time
long convertedTime = dt.getTime() - (fromOffset - toOffset);
Date d2 = new Date(convertedTime);
return d2;
}
OUT PUT:
Converted Date : Tue Apr 18 06:28:09 IST 2017
Can someone please help on this: I found lot of solutions on converting IST Date time to PST String but not IST/EST Date to PST Date.
As I mentioned above we can format to a String, but I am looking for an example of converting back to Date
You should look into Java 8's new Date API that handles timezones directly
// Get the current date and time
ZonedDateTime date1 = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]");
System.out.println("date1: " + date1);
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println("Zoned Date Time: " + zonedDateTime);
ZoneId id = ZoneId.of("Europe/Paris");
System.out.println("ZoneId: " + id);
ZoneId currentZone = ZoneId.systemDefault();
System.out.println("CurrentZone: " + currentZone);
Prints :
date1: 2007-12-03T10:15:30+05:00[Asia/Karachi]
Zoned Date Time: 2017-04-18T09:52:09.045-04:00[America/New_York]
ZoneId: Europe/Paris
CurrentZone: America/New_York
Since some readers here will use Java 8 or later and some Java 7 or earlier, I will treat both.
I recommend you use the java.time classes introduced in Java 8 if you can:
ZoneId targetTz = ZoneId.of("America/Los_Angeles");
String string = "Tue Apr 18 18:58:09 +0300 2017";
DateTimeFormatter format = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss ZZZ uuuu",
Locale.ENGLISH);
ZonedDateTime sourceTime = ZonedDateTime.parse(string, format);
ZonedDateTime targetTime = sourceTime.withZoneSameInstant(targetTz);
String result = targetTime.format(format);
System.out.println(result);
This prints:
Tue Apr 18 08:58:09 -0700 2017
You said you wanted a PST date, and this is exactly what the ZonedDateTime gives you: date and time with time zone information.
In the example I am giving a zone offset, +0300 (corresponding to Israel Daylight Time) in the string. I understood that it wasn’t important to you how the time zone was given. I want to avoid the three and four letter time zone abbreviations like IST. Not only may IST mean either Irish Standard Time, Israel Standard Time or India Standard Time. I furthermore noticed that the java.time classes pick up 18:58:09 IST as 18:58:09 IDT (UTC+3) because it knows Israel is on DST on April 18; the SimpleDateFormat that I return to below takes IST more literally and interprets 18:58:09 IST as 18:58:09 +0200, which is 1 hour later in UTC.
You can use the java.time classes with Java 1.7 if you want. You can get them in the ThreeTen Backport.
If you don’t want to use java.time, the way to do it with the outdated classes from Java 1.0 and 1.1 is not that different in this case, only I cannot give you the PST date you asked for:
TimeZone targetTz = TimeZone.getTimeZone("America/Los_Angeles");
String string = "Tue Apr 18 18:58:09 +0300 2017";
SimpleDateFormat dt = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZ yyyy", Locale.ENGLISH);
Date d = dt.parse(string);
dt.setTimeZone(targetTz);
String result = dt.format(d);
System.out.println(result);
It prints the same result as above. However, you notice there is only one Date object. A Date object cannot hold any time zone information, so if you need this, you will have to bring the targetTz object along with d. It’s a common misunderstanding that there’s supposed to be a time zone in the Date object, probably greatly helped by the fact that its toString() prints a time zone. This is always the JVM’s default time zone and doesn’t come from the Date object, though.

Java: Date/Time from Database to milliseconds, hour disappearing

I am having an issue with Dates and timezones.
I have a MySQL InnoDB database which holds two fields DATE(yyyy-MM-dd) and TIME(HH:mm:ss). These are known as to be UTC (0 GMT). My computer is based in CET (+1 GMT).
• dateObject is the result from this resultSet.getTime("date_field") (java.sql.Date)
• timeObject is a result from this resultSet.getDate("time_field") (java.sql.Time)
In the database DATE is stored as 2014-02-22 and TIME 15:00
System.out.println("Untouched "+dateObject+" "+timeObject);
long date = dateObject.getTime();
long time = timeObject.getTime();
System.out.println("Touched "+new Date(date+time));
Results in the following output:
Untouched 2014-02-22 15:00:00
Touched Sat Feb 22 14:00:00 CET 2014
Why is one hour being skipped off the Touched output? I was expecting the following:
Untouched 2014-02-22 15:00:00
Touched Sat Feb 22 15:00:00 CET 2014
To rumble things up I have tried with the following also:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date(date+time)));
And result:
2014-02-22 14:00:00
All in all. I am expecting GMT+1 to show 16:00(local) and GMT+0 to display 15:00
I think I did answer ma question (Remember timeObject in the db is 15:00:00 at UTC):
TimeZone tz = TimeZone.getTimeZone("Gmt0");
SimpleDateFormat sdfFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdfFull.setTimeZone(tz);
Date updateDate = sdfFull.parse(dateObject.toString()+" "+timeObject.toString());
System.out.println(updateDate);
Results in what I was hoping for:
Sat Feb 22 16:00:00 CET 2014
The reason is similar to this SO-answer. But note following details about toString().
java.util.Date.toString() => output dependent on your system time zone
in format pattern "EEE MMM dd HH:mm:ss zzz yyyy"
java.sql.Date.toString() => output in format "yyyy-MM-dd" (your dateObject)
java.sql.Time.toString() => output in format "HH:mm:ss" (your timeObject)
The sql representations are not dependent on time zone. So you compare apples and peaches.
Supplementary remark:
I have invested more in testing and found:
java.sql.Date dateObj = new java.sql.Date(2014 - 1900, Calendar.FEBRUARY, 22);
Time timeObj = new Time(15, 0, 0);
Time midnight = new Time(0, 0, 0);
Date d = new Date(dateObj.getTime() + timeObj.getTime());
System.out.println("dateObj: " + dateObj + "/" + dateObj.getTime());
// dateObj: 2014-02-22/1393023600000, one hour less than a full day because of UTC-long
System.out.println("timeObj: " + timeObj + "/" + timeObj.getTime());
// timeObj: 15:00:00/50400000 => one hour less as UTC-long
System.out.println("midnight: " + midnight + "/" + midnight.getTime());
// midnight: 00:00:00/-3600000 => one hour less, negative!
System.out.println(new Date(dateObj.getTime())); // Sat Feb 22 00:00:00 CET 2014
System.out.println(new Date(timeObj.getTime())); // Thu Jan 01 15:00:00 CET 1970
System.out.println(d); // Sat Feb 22 14:00:00 CET 2014
So I strongly suspect following effect: Both dateObject and timeObject are been calculated your system time zone, therefore their utc-long values show both one hour less - the time zone offset. If you combine both in one Date-object by just summarizing up then one of both deltas gets lost because one single date object cannot take in account two offsets.
Conclusion: You tried to combine date and time by summarize their utc-longs, but this is in general a faulty approach. Date plus Date is not Date, but undefined! In domain-specific language you can only add a duration/period to a date/time. So a solution having a midnight object could be:
Date d = new Date(dateObj.getTime() + timeObj.getTime() - midnight.getTime());
System.out.println(d); // Sat Feb 22 15:00:00 CET 2014, correct - what you wanted

wrong time calculating in Java

when I want to sum two dates in java it does not work:
System.out.println(date + " <---- date");
System.out.println(time + " <---- time");
System.out.println(new Date(date.getTime() + time.getTime()) + " <---- new Date(time.getTime() + date.getTime())");
leads to following output:
Wed Nov 06 00:00:00 CET 2013 <---- date
Thu Jan 01 11:51:14 CET 1970 <---- time
Wed Nov 06 10:51:14 CET 2013 <---- new Date(time.getTime() + date.getTime())
... but if i work with Calender it works!
Calendar calendar = Calendar.getInstance();
calendar.setTime(time);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int min = calendar.get(Calendar.MINUTE);
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, min);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date myDate = calendar.getTime();
System.out.println(myDate);
results in
Wed Nov 06 11:51:00 CET 2013
which is correct
Can anybody explain me why?
Fundamentally, you've got problems with time zones here. The fact that you're using a java.util.Date to represent a time of day is messing you up to start with. Your time of 11:51:14 CET is actually 10:51:14 UTC, so when you add the result of calling time.getTime(), you're only adding "just under 11 hours" rather than "just under 12 hours". The use of inappropriate data types makes all this hard to work with and understand.
I'd strongly recommend using Joda Time for all of this. Then you can start with a LocalDate and LocalTime, combine them into a LocalDateTime and then work out if you want to apply a particular time zone.
Using the right data types, which mean exactly what you're trying to convey, makes a huge difference for date/time work.

Categories

Resources