Search code examples
datetimejava-8timezonezoneddatetime

XMLGregorianCalendar format date in ZonedDateTime


I have a function which takes Date and gives XMLGregorianCalendar formatted date as below which returns date as 2017-11-30T00:00:00.000-08:00 when date provided as 2017-11-30

public static String xmlDate(Date date) {
    XMLGregorianCalendar xmlDate = null;
    if (date != null) {
        GregorianCalendar gc = new GregorianCalendar();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        gc.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
        gc.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        gc.set(Calendar.MILLISECOND, 0);

        try {
            xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
        } catch (DatatypeConfigurationException e) {
            //exception
        }
    }
    return xmlDate.toString();
}

I'm trying to rewrite above function with Java 8 ZonedDateTime but getting date as 2017-11-29T00:00:00-08:00 .How can I get the exact output same as the above function? Also I dont understand why the date is 29 instead of 30.

public static String zonedDatetime(Date date) {
    return ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("America/Los_Angeles"))
            .truncatedTo(ChronoUnit.DAYS)
            .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}

Solution

  • Assuming that date is this instant, then the reason you are getting the 29th is because that is the date in Los Angeles at this moment (22:53 PST).

    If you want to match the local date, then you're probably after something like this:

    return ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())
                .withZoneSameLocal(ZoneId.of("America/Los_Angeles"))
                .truncatedTo(ChronoUnit.DAYS)
                .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)