I’m developing a client to a web service which exposes (.wsdl) contract, which requires yyyy-MM-dd format for 1 on the request parameters , however auto generated POJOS based on the .wsdl create the date attribute as Type XMLGregorianCalendar.
My issue is NOT converting to or from XMLGregorianCalendar see my utility below:
public static XMLGregorianCalendar toXMLGregorianCalendar(Calendar c){
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(c.getTimeInMillis());
XMLGregorianCalendar xc= null;
try {
xc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
} catch (DatatypeConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return xc;
}
My issue is going from XMLGregorianCalendar to Date/Calendar adds extra time/unwanted data to my yyyy-MM-dd when calling calendar.getTime();
In a particular code segment I need to go from XMLGregorianCalendar to Date
if (repairOrderType.getCloseDate() != null) {
LOG.debug("ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() BEFORE:"
+ repairOrderType.getCloseDate());
String date = repairOrderType.getCloseDate().getYear() + "-"
+ repairOrderType.getCloseDate().getMonth() + "-"
+ repairOrderType.getCloseDate().getDay();
//Approach #1, trying to remove hour,minute,sec values by calendar.clear() method , not successful
Calendar calendar = Calendar.getInstance();
calendar.set(repairOrderType.getCloseDate().getYear(),
repairOrderType.getCloseDate().getMonth(),
repairOrderType.getCloseDate().getDay());
calendar.clear(Calendar.HOUR);
calendar.clear(Calendar.MINUTE);
calendar.clear(Calendar.SECOND);
calendar.clear(Calendar.MILLISECOND);
/*Approach#2 , trying to remove hour,minute,sec values using SimpleDateFormat ,
* also not successful. SimpleDateFormat or DateFormat are use to format String output NOT remove internal data
*
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = formatter.getCalendar();
calendar.set(repairOrderType.getCloseDate().getYear(),
repairOrderType.getCloseDate().getMonth(),
repairOrderType.getCloseDate().getDay());
*/
LOG.debug("ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() AFTER:"
+ calendar.getTime());
repairOrder.setCloseDate(calendar.getTime());
}
Output:
27-Nov-2012 18:10:39.743 DEBUG com.tms.owners.integration.nsh.mapping.ServiceHistoryMapper - ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() BEFORE:2012-04-30
27-Nov-2012 18:10:51.413 DEBUG com.tms.owners.integration.nsh.mapping.ServiceHistoryMapper - ServiceHistoryMapper, processRepairOrders() , repairOrderType.getCloseDate() AFTER:Wed May 30 18:00:00 PDT 2012
As you can see above BEFORE date is BEFORE:2012-04-30 and AFTER date is May 30 18:00:00 PDT 2012 with unwanted hours "18:00:00 PDT".
Below is my actual request XML sent to the service:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns4:VehicleServiceHistoryDetails
xmlns="urn:tms.toyota.com/Components" xmlns:ns2="urn://esb.ari.xxxxxx.com/2008/12/10/schemas/common/Customer"
xmlns:ns3="urn:incentives.ari.xxxxxx.com/StandardHeader"
xmlns:ns4="urn://esb.ari.xxxxxx.com/2008/12/10/schemas/History"
xmlns:ns5="http://ice.ari.xxxxxx.com/EMF" xmlns:ns6="urn:ari.xxxxxx.com/rtmheader">
<ns5:ApplicationArea>
<ns5:CreationDateTime>2012-11-27T18:11:23.071-08:00
</ns5:CreationDateTime>
<ns5:Sender />
<ns5:UserArea />
</ns5:ApplicationArea>
<ns4:VehicleServiceHistoryDataArea>
<ns4:VehicleServiceHistoryHeader>
<ns3:TimeStamp>2012-11-27T18:11:23.071-08:00</ns3:TimeStamp>
<ns3:SourceSystem>TOO</ns3:SourceSystem>
<ns4:SourceKey>TOY1TWXE</ns4:SourceKey>
</ns4:VehicleServiceHistoryHeader>
<ns4:VehicleServiceHistory>
<ns4:VIN>XXXXXXXXXXXXXXXX</ns4:VIN>
<ns4:RepairOrder>
<ns2:RepairOrderDealer>
<DealerNumber>29059</DealerNumber>
</ns2:RepairOrderDealer>
<ns2:RepairOrderNumber>0088745</ns2:RepairOrderNumber>
<ns2:CloseDate>2012-05-30-07:00</ns2:CloseDate>
</ns4:RepairOrder>
</ns4:VehicleServiceHistory>
</ns4:VehicleServiceHistoryDataArea>
</ns4:VehicleServiceHistoryDetails>
</S:Body>
</S:Envelope>
You can see in the request xml in the 2012-05-30-07:00 that extra "-07:00" data is added i just want 2012-05-30.
Thanks
The in context of XML datatypes the XMLGregorianCalendar is created via factory methods in javax.xml.datatype.DatatypeFactory which seems to have a method called newXMLGregorianCalendarDate(int year, int month, int day, int timezone);
So I created a utility method :
public static XMLGregorianCalendar toXMLGregorianCalendarDateOnly(Calendar c){
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(c.getTimeInMillis());
XMLGregorianCalendar xc= null;
try {
xc = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(gc.get(Calendar.YEAR),Calendar.MONTH,Calendar.DAY_OF_MONTH,DatatypeConstants.FIELD_UNDEFINED);
} catch (DatatypeConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return xc;
}
The issue is resolved now, we are getting the desired yyyy-MM-ddd.
You can also write it in a following manner which is more readable:
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(c.getTimeInMillis());
XMLGregorianCalendar calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
calendar.setMillisecond(DatatypeConstants.FIELD_UNDEFINED);
calendar.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
I used the below code to resolve the same problem.
public static XMLGregorianCalendar toXMLGregorianCalendarWithoutTimeStamp(String date) {
Date mDate = null;
GregorianCalendar cal = new GregorianCalendar();
XMLGregorianCalendar xmlGregorianCalendar;
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
try {
mDate = df.parse(date);
cal.setTime(mDate);
xmlGregorianCalendar = DatatypeFactory.newInstance()
.newXMLGregorianCalendarDate(cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH) + 1,
cal.get(Calendar.DAY_OF_MONTH),
DatatypeConstants.FIELD_UNDEFINED);
return xmlGregorianCalendar;
} catch (DatatypeConfigurationException e) {
LOGGER.error("Error in getCustomerCDRResponse Date Formate Type Configuartion :: " + e);
} catch (ParseException e) {
LOGGER.error("Error in getCustomerCDRResponse Date Parsing :: " + e);
}
return null;
}
try this.
Date dob=null;
DateFormat df=new SimpleDateFormat("dd/MM/yyyy");
dob=df.parse( "10/02/2014 11:15:00" );
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(dob);
XMLGregorianCalendar xmlDate3 = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH),DatatypeConstants.FIELD_UNDEFINED);
System.out.println(xmlDate3);
If you are using javax.xml.bind.Marshaller to prepare SOAP body then the root of the unwanted bahavior is in yours xlmns:ns2. The field ns2:CloseDate is of type (or some other type wichich include date and time):
{http://www.w3.org/2001/XMLSchema}dateTime
change it to (or other date type without hour and minute):
{http://www.w3.org/2001/XMLSchema}date
If you don't manage this xlmns, just accept that yours CloseDate must have time defined. Without it called web service would have unapropiate time declaration (I don't know exactly value, but I'm bet on 0:00)
Related
I'm only getting this string "+0800" for a timezone from ihealth api. How can I get the corresponding java timezone id (like "US/Central") from this.
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("Z");
try {
Date date = sdf.parse("+0800");
cal.setTime(date);
System.out.println(cal.getTimeZone().getID());
} catch (Exception e) {
System.out.println("error" + e.getMessage());
}
but this always prints "Etc/UTC" which is not "+0800". what am I missing here?
The difficulty in what you are asking is that there are (almost?) always many timezone names associated with a given offset. So, for an offset of "+0800" we can do
int rawOffset = 8 * 3600000; // +0800 hours converted to milliseconds
String[] tzIds = java.util.TimeZone.getAvailableIDs(rawOffset);
for (String id : tzIds) {
System.out.println(id);
}
and see the list
Antarctica/Casey
Asia/Brunei
Asia/Choibalsan
Asia/Chongqing
Asia/Chungking
Asia/Harbin
Asia/Hong_Kong
Asia/Kashgar
Asia/Krasnoyarsk
Asia/Kuala_Lumpur
Asia/Kuching
Asia/Macao
Asia/Macau
Asia/Makassar
Asia/Manila
Asia/Shanghai
Asia/Singapore
Asia/Taipei
Asia/Ujung_Pandang
Asia/Ulaanbaatar
Asia/Ulan_Bator
Asia/Urumqi
Australia/Perth
Australia/West
CTT
Etc/GMT-8
Hongkong
PRC
Singapore
If you want "the corresponding java timezone id" (emphasis mine) then I guess you'll have to pick one. ;)
Provided you use Java 8 you can use ZoneOffset
For example
ZoneOffset zoneOffset = ZoneOffset.of("+0200");
TimeZone timezone = TimeZone.getTimeZone(zoneOffset));
Edit: ZoneOffset.of() accepts offsetId, which is different from the 4 digits representation, so this would not solve the problem.
Try this:
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("Z");
try {
Date date = sdf.parse("-0600");
cal.setTime(date);
System.out.println(sdf.format(date));
} catch (Exception e) {
System.out.println("error" + e.getMessage());
}
I have the following operation which should parse the date in the specified format. But it does not parse and throws an exception of unparseable.
Can someone please correct me where i am wrong. The field is TimeStamp and DB is Oracle.
private XMLGregorianCalendar stringToXMLGregorianCalendar(String s)
throws DatatypeConfigurationException, ParseException {
XMLGregorianCalendar result = null;
Date date = null;
SimpleDateFormat simpleDateFormat;
GregorianCalendar gregorianCalendar;
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
date = simpleDateFormat.parse(s);
gregorianCalendar = (GregorianCalendar) GregorianCalendar
.getInstance();
gregorianCalendar.setTime(date);
result = DatatypeFactory.newInstance().newXMLGregorianCalendar(
gregorianCalendar);
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
According to the JavaDoc, "yyyy-MM-dd'T'HH:mm:ss.SSSZ" would equate to something like 2001-07-04T12:08:56.235-0700. If you notice, the T is still there.
In your error, the date seems to be the following: 2015-10-08 05:00:00.0” which is of the form yyyy-MM-dd HH:mm:ss.S, but you are using this format: yyyy-MM-dd'T'HH:mm:ss. You need to omit the extra 'T' and include an extra .S to match the milli secon aspect of it.
Im retrieving some values from a json service and the retrieved datetime values are stored in UTC format.
i've tried a lot of sample codes to convert the datetime values to user local timezone but im still getting the same value after conversion.
This is what i have actually: (copied from other posts)
String sJsonDate = "2015-07-08T12:08:13.0625+00:00";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date localDateTime = simpleDateFormat.parse(sJsonDate);
} catch (ParseException e) {
e.printStackTrace();
}
The result value (localDateTime) is the same as the original value.
I am in Paraguay (GMT-4) and the resulting values needs to be minus one hour diference, like this: ("2015-07-08 07:13:25") (The values are stored in Argentina)
Help please!
I've found the solution, we are using day light savings so i had to disccount one hour to the resulting datetime.
So, i share the code for someone else:
public Date getDateInTimeZone(Date currentDate, String timeZoneId) {
TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);
Date localDateTime = new Date(currentDate.getTime() + timeZone.getOffset(currentDate.getTime()));
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(localDateTime.getTime());
if (timeZone.useDaylightTime()) {
// time zone uses Daylight Saving
cal.add(Calendar.MILLISECOND, timeZone.getDSTSavings() * -1);// in milliseconds
}
return cal.getTime();
}
Usage:
String sDate = "2015-07-08T12:08:13.0625+00:00";
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date theDate = simpleDateFormat.parse(sDate);
Date localDateTime = getDateInTimeZone(theDate, TimeZone.getDefault().getID());
} catch (ParseException e) {
e.printStackTrace();
}
I am using the below code to set a XMLGregorianCalendar field in webservice
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
Date dateOfBirth = null;
try {
dateOfBirth = format.parse(adult.getDob_day() + "-" + adult.getDob_month() + "-"
+ adult.getDob_year() + " 00:00:00");
} catch (Exception e) {
log.error("Error while parsing dateOfBirth. Cause " + e.getMessage());
e.printStackTrace();
}
passenger.setDateOfBirthField(convertToXMLCalendar(dateOfBirth));
The method convertToXMLCalendar is as below
private XMLGregorianCalendar convertToXMLCalendar(Date date) {
XMLGregorianCalendar xmlCalendar = null;
GregorianCalendar calendar = new GregorianCalendar();
if (date != null) {
try {
calendar.setTime(date);
xmlCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
} catch (Exception e) {
log.error("Error while converting to XMLGregorianCalendar. Cause " + e.getMessage());
// e.printStackTrace();
}
}
return xmlCalendar;
}
My server location timezone is +03:00. But in few random scenarios the timezone is being send as +04:00 in SOAP request.
<ns7:dateOfBirthField>1955-08-27T00:00:00.000+04:00</ns7:dateOfBirthField>
Due to this the service is receiving the date as one day lesser than actual date. If I send 03-06-2014 00:00:00 its reaching the service as 02-06-2014 11:00:00.
If I set the time as 12:00:00 instead of 00:00:00 will it fix the issue. But whats the reason for this timezone change?
Your SimpleDateFormat doesn't specify a time zone, so it's using your local time zone. I would suggest:
Not parsing a value at all. You've got the individual day, month and year - so use that directly with a calendar!
Pass a Calendar to convertToXMLCalendar instead of a date... if you need to at all (see below)
Specify the time zone of the calendar as UTC if you really want to... although fundamentally I'd expect a dateOfBirth value to be just a date, to be honest, e.g. 1955-08-27. That way you're not specifying a time zone at all.
In fact, given that you've got the year/month/day, I'd just create an XMLGregorianCalendar directly from those values:
XMLGregorianCalendar calendar = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(adult.getDob_year(),
adult.getDob_month(),
adult.getDob_day(),
DatatypeConstants.FIELD_UNDEFINED); // No time zone
Then you're representing a date rather than a dateTime, which is what fits your data.
Your calendar does not specify the time zone. I believe, just by modifying the convertToXMLCalendar method, we can get rid of this problem
private static XMLGregorianCalendar convertToXMLCalendar(Date date) {
XMLGregorianCalendar xmlCalendar = null;
GregorianCalendar calendar = new GregorianCalendar();
// You can set GMT time zone or Default or whatever
//TimeZone myzone = TimeZone.getTimeZone("GMT");
TimeZone myzone = TimeZone.getDefault();
calendar.getInstance(myzone);
if (date != null) {
try {
calendar.setTime(date);
xmlCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
} catch (Exception e) {
e.printStackTrace();
}
}
return xmlCalendar;
}
I am retrieving data from a webservice that provides a timestamp in the form of HH:mm:ss I am using SimpleDateFormat to convert this string into a date object then change its timezone if needed and also convert it from 24hour to 12 hour time.
Problem: When a time is fed in for 12am it looks like this 00:00:00
so 12:05 is 00:05:00
When i get the results they look like this.
times fed in 22:00:00 to 00:01:00
times retrieved 10:00 pm to 0:01 am
I have been looking around to see if there is a way to fix it but i feel like i will need to make a special case and parse the string myself if it has a 0 in the hours place.
Any help would be greatly appreciated.
public String parseTime(String time) {
String mTime = null;
TimeZone thisTimeZone = TimeZone.getDefault();
TimeZone ourTimeZone = TimeZone.getTimeZone("America/Los_Angeles");
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss", Locale.US);
SimpleDateFormat sdfThisTimeZone = new SimpleDateFormat("K:mm:a",
Locale.getDefault());
Date date = null;
sdfThisTimeZone.setTimeZone(thisTimeZone);
sdf.setTimeZone(ourTimeZone);
try {
date = sdf.parse(time);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mTime = sdfThisTimeZone.format(date.getTime());
//**********************************New: Does Not Work********************************
DecimalFormat nft = new DecimalFormat("00"); mTime = nft.format(mTime);
//**********************************New **********************************************
return mTime;
}
I have tried the line using DecimalFormat but i just copied it into the code for now to see if it would work. Unfortunately it made my app crash. The code that i have posted is executed inside an Async Task so i am not sure if that makes any difference but still thankyou for your help. Eventually i will solve this. But for now it is such a small detail that only occurs for 1 hour at 12am that i am moving on to bigger issues. If anyone can shed some light on this that would be awesome.
String getConvertedDateTime (String dateTime) {
String convertedDateTime = dateTime;
if (convertedDateTime != null
&& !convertedDateTime.equalsIgnoreCase("")
&& !convertedDateTime.equalsIgnoreCase("null")) {
try {
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Calendar calendar = Calendar.getInstance();
java.util.Date convertedDate = formatter
.parse(convertedDateTime);
formatter.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
convertedDateTime = formatter.format(convertedDate.getTime());
} catch (Exception e) {
e.printStackTrace();
}
}
return convertedDateTime;
}