Search code examples
javaxmldatetime-formatxmlgregoriancalendar

Format LocalDateTime to XMLGregorianCalender with offset


I have an instance of LocalDateTime.

I need to map it XMLGregorianCalendar (using JAXB here) and in the end XML, i would like the time to look like following in XML document: 2020-03-04T19:45:00.000 + 1:00 (1 hour is the offset from UTC).

I have tried to convert the LocalDateTime to a String using DateTimeFormatter and then map it to XMLGregorianCalender.

I have two questions now:

  1. I have not been able to find any formatter in DateTimeFormatter which formats the time with offset to UTC? Does something like this exist or I need to define my formatter pattern?

    Secondly, if I'm able to format the LocalDateTime in String format I need, is it enough if I just create a XMLGregorianCalendar from string represenation?


Solution

  • If the time zone offset is to be derived from the default time zone of the JVM, then code it like this:

    LocalDateTime localDateTime = LocalDateTime.now();
    ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault()); // <== default
    OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime();
    XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
    
    System.out.println(localDateTime);        // 2020-03-04T15:58:09.604171800
    System.out.println(zonedDateTime);        // 2020-03-04T15:58:09.604171800-05:00[America/New_York]
    System.out.println(offsetDateTime);       // 2020-03-04T15:58:09.604171800-05:00
    System.out.println(xmlGregorianCalendar); // 2020-03-04T15:58:09.604171800-05:00
    

    If you want to hardcode an offset of +01:00, then do it like this:

    LocalDateTime localDateTime = LocalDateTime.now();
    OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.ofHours(1)); // <== hardcoded
    XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
    
    System.out.println(localDateTime);        // 2020-03-04T16:00:04.437550500
    System.out.println(offsetDateTime);       // 2020-03-04T16:00:04.437550500+01:00
    System.out.println(xmlGregorianCalendar); // 2020-03-04T16:00:04.437550500+01:00
    

    Or like this:

    LocalDateTime localDateTime = LocalDateTime.now();
    XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
    xmlGregorianCalendar.setTimezone(60); // <== hardcoded
    
    System.out.println(localDateTime);        // 2020-03-04T16:03:09.032191
    System.out.println(xmlGregorianCalendar); // 2020-03-04T16:03:09.032191+01:00