I have a birthday (Date object) that I would like to convert to UTC time.
I am able to use formatting to convert my locale time to UTC time by SimpleDatePattern. However when I format it, it converts the Date object to String. I tried parsing it (which returns a Date object) but converts it to local time system again. Here is my code below. Any help on converting the birthday field to UTC time while remaining a Date object and not a string?
public Date getBirthDay() {
if (birthDay == null) {
return null;
}
DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String formattedBirthDate = utcFormat.format(birthDay);
try {
System.out.println("I am here within try block" + utcFormat.parse(formattedBirthDate));
birthDay = utcFormat.parse(formattedBirthDate);
} catch (ParseException e) {
e.printStackTrace();
}
return (Date) birthDay.clone();
}
I got a timestamp as follows, 2019-10-17T07:10:39.021+10:30 but when I parse through the SimpleDateFormat then print again, it appear as 2019-10-17T07:40:39.021+11:00
Looks like it added the 30min to time then change the time zone. Is there is a way to fix that.
Date date = null;
String value = "2019-10-17T07:10:39.021+10:30";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.getDefault());
System.out.println("input :" + value);
try {
date = sdf.parse(value);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("output :" + sdf.format(date));
Result
input :2019-10-17T07:10:39.021+10:30
output :2019-10-17T07:40:39.021+11:00
Should be same as input.
The date string you have 2019-10-17T07:10:39.021+10:30consists of offset, so from java-8 you can use OffsetDateTime
A date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system, such as 2007-12-03T10:15:30+01:00.
OffsetDateTime dateTime = OffsetDateTime.parse(date);
System.out.println(dateTime.toString()); //2019-10-17T07:10:39.021+10:30
Why are you using Locale.getDefault(), that parameter is not necessary. Can you try just calling it as below,
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
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());
}
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’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)