79161195

Date: 2024-11-06 02:26:23
Score: 0.5
Natty:
Report link

What does your XMLGregorianCalendar look like?

XMLGregorianCalendar is a flexible beast in that each of its fields -- year, month, day, hour, minute, second and UTC offset -- may be defined or undefined (UTC offset is confusingly called timezone in XML parlance). To work with it we first need to know which fields are defined. You probably know that in your case, only you haven‘t told us. For a string containing date and time of day we need those. More precisely I should say that we need year, month, day, hour, minute and second. So I will assume that we have all of those. For UTC offset we either need it to be in the XMLGregorianCalendar (preferred), or we need to know which time zone was assumed when the XMLGregorianCalendar was constructed. Under all circumstances we need to know for which time zone to write the string.

java.time

I recommend that you use java.time, the modern Java date and time API, to the greatest extend possible for your date and time work. So my code includes converting XMLGregorianCalendar to a modern type, either OffsetDateTime or LocalDateTime depending UTC offset being defined in the XMLGregorianCalendar.

So a suggestion is:

    ZoneId defaultAssumedSourceZone = ZoneId.of("Europe/Tallinn");
    ZoneId desiredTargetZone = ZoneId.of("Asia/Kabul");
    DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);

    XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar("2013-02-04T13:12:45+01:00");

    if (xgcal.getXMLSchemaType() != DatatypeConstants.DATETIME) {
        throw new IllegalStateException("We need year, month, day, hour, minute and second; got " + xgcal);
    }

    ZonedDateTime targetZdt;
    if (xgcal.getTimezone() == DatatypeConstants.FIELD_UNDEFINED) { // No UTC offset
        LocalDateTime dateTime = LocalDateTime.parse(xgcal.toString());
        ZonedDateTime sourceZdt = dateTime.atZone(defaultAssumedSourceZone);
        targetZdt  = sourceZdt.withZoneSameInstant(desiredTargetZone);
    } else { // UTC offset included; use it
        OffsetDateTime sourceDateTime = OffsetDateTime.parse(xgcal.toString());
        targetZdt  = sourceDateTime.atZoneSameInstant(desiredTargetZone);
    }
    String formattedDateTime = targetZdt.format(formatter);

    System.out.println(formattedDateTime);

When running this snippet in US English locale, output was:

2/4/13, 4:42 PM

It‘s not the format you asked for. Please consider it anyway. It‘s Java‘s built-in localized format for the locale, so it‘s likely to make the users in that locale happy. And it adjusts easily to other locales. Run in Spanish locale, for example:

4/2/13, 16:42

If your users insist on MM/dd/yyyy hh:mm for a reason that I cannot guess, specify that:

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm", Locale.ROOT);

02/04/2013 15:42

Let‘s try the code with a XMLGregorianCalendar with undefined UTC offset too:

    XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar("2013-02-04T13:12:45");

2/4/13, 3:42 PM

Reasons:
  • Blacklisted phrase (0.5): I cannot
  • Whitelisted phrase (-1): in your case
  • Long answer (-1):
  • Has code block (-0.5):
  • Contains question mark (0.5):
  • Unregistered user (0.5):
  • Starts with a question (0.5): What do
  • Low reputation (1):
Posted by: Noah Smith