Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
1.5.4, 1.6.2
-
None
-
None
-
Diverse linux (at least)
Description
GIVEN ConverterUtil.convertToDate("1940-01-01")
THEN resulting date is one day before at 23:00
GIVEN ConverterUtil.convertToDate("1900-01-01Z")
THEN resulting date is one day before at 23:00
---------------------------------------------------------------------------------------------------------
Test that reproduce the issue:
@Test
public void testCustomConvertToDateTimeZone() {
for (int year = 2012; year > 1800; year--) {
for (int month = 12; month > 0; month--)
}
}
public void assertParsedDateFieldsEquals(int year, int month, int day, Date date)
{ Assert.assertNotNull(date); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); String message = "failed conversion " + createFormattedDate(year, month, day) + " not equals " + date; Assert.assertEquals(message, year, calendar.get(Calendar.YEAR)); Assert.assertEquals(message, month, calendar.get(Calendar.MONTH) + 1); Assert.assertEquals(message, day, calendar.get(Calendar.DAY_OF_MONTH)); }public String createFormattedDate(int year, int month, int day, String suffix)
{ return new DecimalFormat("0000").format(year) + "-" + new DecimalFormat("00").format(month) + "-" + new DecimalFormat("00").format(day) + suffix; }-------------------------------------------------------------------
The following implementation solves this issue. I'm not 100% sure it works in all other cases.
Essentially I'm setting the timezone offset for the particular date because of the historical information that TimeZone may contain..
Another problem I found is that I could not find a way to override the static method so I had to manually change the wsdl2java generated code.
/**
- Converts a given string into a date. Code from Axis1 DateDeserializer.
- @param source
- @return Returns Date.
*/
public static Date convertToDate(String source) {
// the lexical form of the date is ''? yyyy '' mm '-' dd zzzzzz?
if ((source == null) || source.trim().equals(""))
source = source.trim();
boolean bc = false;
if (source.startsWith("-"))
int year = 0;
int month = 0;
int day = 0;
Integer timeZoneOffSet = null;
if (source.length() >= 10) {
// first 10 numbers must give the year
if ((source.charAt(4) != '') || (source.charAt(7) != ''))
year = Integer.parseInt(source.substring(0, 4));
month = Integer.parseInt(source.substring(5, 7));
day = Integer.parseInt(source.substring(8, 10));
if (source.length() > 10) {
String restpart = source.substring(10);
if (restpart.startsWith("Z"))
else if (restpart.startsWith("+") || restpart.startsWith("-") || restpart.startsWith("T")) {
// this is a specific time format string
if (restpart.charAt(3) != ':')
int hours = Integer.parseInt(restpart.substring(1, 3));
int minits = Integer.parseInt(restpart.substring(4, 6));
timeZoneOffSet = ((hours * 60) + minits) * 60000;
if (restpart.startsWith("-"))
} else
{ throw new RuntimeException("In valid string sufix"); } }
} else
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setLenient(false);
calendar.set(Calendar.YEAR, year);
// xml month stars from the 1 and calendar month is starts with 0
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DAY_OF_MONTH, day);
if (timeZoneOffSet != null)
{ calendar.set(Calendar.ZONE_OFFSET, timeZoneOffSet); }else
{ calendar.set(Calendar.ZONE_OFFSET, TimeZone.getDefault().getOffset(calendar.getTimeInMillis())); } // set the day light off set only if time zone
if (source.length() >= 10)
calendar.getTimeInMillis();
if (bc)
return calendar.getTime();
}