I'm using org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDate(StringDate)
to parse the input string date from XML to JAVA date. But i got a Date objects with day-1 value.
For example
<birth>1939-11-19+01:00</birth>
I want to ignore the offset. I want only the date, so no matter what the offset is, I should get
Sun Nov 19 00:00:00 CET 1939
But I do get:
Sat Nov 18 23:00:00 CET 1939
The issue is at the level of date's time offset. I tried to fix it with ignoring the time offset but that didn't work. I'm using java 6 (constraint project). Any ideas?
My best attempt at a minimal, complete and verifiable example:
public static Date parse(final String str) {
Calendar c = DatatypeConverter.parseDateTime(str);
System.out.println(str + "\t" + c.getTime().getTime() / 1000);
return c.getTime();
}
java.time
This prints
A
java.time.LocalDate
is a date without time-of-day, so this matches your requirements exactly. At the same timejava.util.Date
and friends are long outdated and have proven poorly designed.java.time
, the modern Java date and time API, is so much nicer to work with. So my first recommendation is you stop here.If you do need a
Date
, for example for a legacy API, first realize that despite the name it does not represent a date. It represents a point in time, and at that point in time the date will not be the same everywhere. This probably caused your problem, as you are aware:parseDate
andparseDateTime
parse your string into 00:00 at the specified offset from UTC on the date in question. At this point in time, the date may not be the same in your time zone, so when you print theDate
you get, thereby invoking itstoString
method, you may get a different date. I understand that you want the time at 0:00 in your own time zone instead (CET, probably Central European Time, in turn a name of several different time zones that may be at offsets 0 or +01 on that date in 1939; the result you observed would make sense in time zones Europe/Paris, Africa/Ceuta, Europe/Andorra, Europe/Madrid and Europe/Monaco, all of which were at offset 0). To convert:This printed
I tested with my time zone set to America/New_York and to Europe/Moscow, and always got
Sun Nov 19 00:00:00
, only in different time zones,EST
andMSK
.Java 6 and ThreeTen Backport
I understand that you have to use Java 6.
java.time
has been backported to Java 6 and 7 in the ThreeTen Backport. So get this from the link at the bottom and add it to your project, and the above code will work except the conversion happens a little differently:You don’t need to rewrite all of your code to use the ThreeTen Backport, and especially not if there are parts where you don’t trust the modern API to behave the way you want. The above snippet can coexist nicely with the code you already have.
The really really old-fashioned way
If you really insist, the way I could find to get the
Date
you want usingDatatypeConverter
andCalendar
:We can’t just change the offset or time zone of the
Calendar
we got from parsing since this will not change its point in time and therefore not theDate
object we get. Instead we need to set a differentCalendar
object to the year, month and day-of-month of the firstCalendar
. The call toclear()
sets hours, minutes, seconds and milliseconds to 0. This snippet too has been tested with my JVM’s time zone set to America/New_York and to Europe/Moscow.Links
java.time
.java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).