When I run below code which converts a xml date to java date, it prints different value(CST) in local vs different value(UTC) in the server running the same code, what could be reason for it? How can I always print this date in CST format which I am getting in my local. I can't use latest java date API and have to use XML based date.
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.XMLGregorianCalendar;
import java.util.Date;
import java.util.TimeZone;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.util.Date;
import java.util.TimeZone;
public class Demo {
public static final TimeZone TIMEZONE = TimeZone.getTimeZone("America/Chicago");
public static Date convertDate(XMLGregorianCalendar value) {
if (value == null) {
return null;
} else {
if (value.getXMLSchemaType() == DatatypeConstants.DATE) {
return value.toGregorianCalendar().getTime();
} else {
return value.toGregorianCalendar(TIMEZONE, null, null).getTime();
}
}
}
public static void main(String[] args) {
try {
// Parse the XML date string into XMLGregorianCalendar
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar("2024-02-09T01:57:33.240-06:00");
// Convert XMLGregorianCalendar to Date
Date date = convertDate(xmlDate);
// Print the result
System.out.println("Date: " + date);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Date: Fri Feb 09 01:57:33 CST 2024 - local output(Intellij - my mac time zone CST)
Date: Fri Feb 09 07:57:33 UTC 2024 - server output(https://www.jdoodle.com/online-java-compiler)
I need to store the date in america/chicago timezone irrespective of the user location and I have no control over the database query
tl;dr
If handed a
XMLGregorianCalendar, convert to modern class.If handed text in standard ISO 8601 format with offset-from-UTC, parse as an
OffsetDateTimeobject.Convert a
XMLGregorianCalendarto ajava.util.Dateby way of java.time:Details
You are using terribly flawed date-time classes that are now legacy. Avoid
XMLGregorianCalendar,GregorianCalendar,Calendar,SimpleDateFormat, and bothDateclasses. They were years ago supplanted by the modern java.time classes defined in JSR 310.Among its many flaws is that
java.util.Date#toStringlies to you. That method interjects the JVM’s current default time zone while generating text to represent the UTC value of the object.When handed a
XMLGregorianCalendarobject, immediately convert to its modern replacement,java.time.ZonedDateTimeby way ofjava.util.GregorianCalendar.If you want to adjust that moment to be seen in a different time zone, apply a
ZoneIdto produce anotherZonedDateTime. The java.time classes are immutable, so you get a new object rather than changing the original.Generate localized text.
If you need to represent the moment in a
ZonedDateTimeas ajava.util.Dateto interoperate with old code not yet updated to java.time, extract anInstant. Pass that tojava.util.Date.from. BothInstantandjava.util.Daterepresent a point on the timeline as seen with an offset from UTC of zero hours-minutes-seconds. The legacy class resolves to milliseconds while the modern class resolves to nanoseconds.