For eg:
we have a List<XMLGregorianCalendar> dates
we need to find the latest date in this list.
Really appreciate your help!
For eg:
we have a List<XMLGregorianCalendar> dates
we need to find the latest date in this list.
Really appreciate your help!
Rather strangely, XMLGregorianCalendar
has a compareTo()
method but does not implement Comparable
, which makes this unnecessarily difficult. I'd be inclined to convert your values to something more Java-friendly like a ZonedDateTime
and work with that. I guess if you're using XMLGregorianCalendar then it's probably because you're using JAXB data binding to XML: the class was invented because at the time, none of the Java date/time options quite matched the XSD data types, but that's no longer really the case.
As Michael Kay said in a comment, in practice date-times in a list usually all have time of day or none of them, and all have UTC offset (“timezone” in the XML parlance) or none. And this is a requirement for your request to make sense. Which of 23:34:45
and 2021-03-31
is later? XMLGregorianCalendar
is flexible enough to accommodate both.
If your XMLGregorianCalendar
objects all have full dates, times and offset, I suggest sorting them as OffsetDateTime
s:
DatatypeFactory factory = DatatypeFactory.newInstance();
List<XMLGregorianCalendar> dates = Arrays.asList(
factory.newXMLGregorianCalendar(
2021, DatatypeConstants.MARCH, 30, 12, 0, 0, 0, 0),
factory.newXMLGregorianCalendar(
2021, DatatypeConstants.MARCH, 30, 9, 0, 0, 0, 60),
factory.newXMLGregorianCalendar(
2021, DatatypeConstants.MARCH, 30, 13, 0, 0, 0, 60));
if (dates.isEmpty()) {
System.out.println("No dates");
} else {
XMLGregorianCalendar maxDate
= Collections.max(dates,
Comparator.comparing(xgc -> OffsetDateTime.parse(xgc.toString())));
System.out.println(maxDate );
}
Output from this snippet is:
2021-03-30T13:00:00.000+01:00
I have chosen my data so that the first and the last item in the list denote the same point in time, only one is on UTC, the other at offset +01:00 (for example Irish Summer Time). That the latter is output is no coincidence. OffsetDateTime.compareTo()
sorts first by point in time (instant in java.time parlance), next by local date-time, and since 13 sounds later than 12, this is chosen.
There are more ways to convert from XMLGregorianCalendar
to OffsetDateTime
. I chose parsing as string because it gives us validation that the XMLGregorianCalendar
has all of date, time and offset.
If date is to be taken literally, your objects represent only dates, instead use LocalDate
. The code is almost the same:
List<XMLGregorianCalendar> dates = Arrays.asList(
factory.newXMLGregorianCalendarDate(2021, DatatypeConstants.MARCH, 26,
DatatypeConstants.FIELD_UNDEFINED),
factory.newXMLGregorianCalendarDate(2021, DatatypeConstants.MARCH, 29,
DatatypeConstants.FIELD_UNDEFINED),
factory.newXMLGregorianCalendarDate(2021, DatatypeConstants.MARCH, 28,
DatatypeConstants.FIELD_UNDEFINED));
if (dates.isEmpty()) {
System.out.println("No dates");
} else {
XMLGregorianCalendar maxDate
= Collections.max(dates,
Comparator.comparing(xgc -> LocalDate.parse(xgc.toString())));
System.out.println(maxDate );
}
2021-03-29
If you have got dates and times but no offsets, use LocalDateTime
in the same way.