Java 如何比较/查找XMLGregoriaCalendar日期列表

Java 如何比较/查找XMLGregoriaCalendar日期列表,java,xml,datetime-comparison,xmlgregoriancalendar,Java,Xml,Datetime Comparison,Xmlgregoriancalendar,例如: 我们有一个列表日期我们需要在此列表中查找最新日期 非常感谢你的帮助 相当奇怪的是,XMLGregorianCalendar有一个compareTo()方法,但没有实现Comparable,这使得这变得不必要的困难。我倾向于将您的值转换为对Java更友好的值,比如ZoneDateTime,并使用它。我猜如果您使用的是XMLGregorianCalendar,那么可能是因为您使用的是JAXB数据绑定到XML:该类的发明是因为当时,没有任何Java日期/时间选项与XSD数据类型完全匹配,但事实

例如: 我们有一个
列表日期
我们需要在此列表中查找最新日期


非常感谢你的帮助

相当奇怪的是,
XMLGregorianCalendar
有一个
compareTo()
方法,但没有实现
Comparable
,这使得这变得不必要的困难。我倾向于将您的值转换为对Java更友好的值,比如
ZoneDateTime
,并使用它。我猜如果您使用的是XMLGregorianCalendar,那么可能是因为您使用的是JAXB数据绑定到XML:该类的发明是因为当时,没有任何Java日期/时间选项与XSD数据类型完全匹配,但事实上已经不是这样了。

正如Michael Kay在评论中所说,实际上,列表中的日期时间通常都有一天中的时间或没有,并且都有UTC偏移量(“XML术语中的时区”)或没有。这是你的要求有意义的一个要求。
23:34:45
2021-03-31
中哪个更晚
XMLGregorianCalendar
足够灵活,可以同时适应这两种情况

如果
XMLGregorianCalendar
对象都有完整的日期、时间和偏移量,我建议将它们排序为
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 );
    }
2021-03-29


如果您有日期和时间,但没有偏移量,请以相同的方式使用
LocalDateTime

dates.stream().max(Comparator.comparing(Function.identity()).get()对较旧的日期使用
min
功能。或者,日期和日历是可比较的对象,您可以将它们放在排序集中而不是列表中,然后获取第一个或最后一个。请参见
NavigableSet.pollFirst
NavigableSet.pollLast
。TreeSet实现了NavigableSet.XMLGregorianCalendar未实现可比性。您的
XMLGregorianCalendar
对象是否表示没有时间的日期,或者是否具有时间和/或UTC偏移量(在API文档中称为时区)?该方法称为
compare
,不应与通常的
compareTo
方法混淆
compare()
可以返回
less
EQUAL
GREATER
不确定
。例如,在(a)2000-01-20T12:00:00和(b)2000-01-20T12:00:00Z之间没有确定的顺序。根据当前使用的时区,(c)可能在2000-01-20T12:00:00+12:00到2000-01-20T12:00:00-13:00之间变化。然而,根据当地法律,这一范围将来可能会扩大或缩小。因此,以下定义使用了更大范围的不确定值:+14:00..-14:00。是的,谢谢。实际上,在给定的数据集中,值通常要么都有时区,要么都没有时区,这就是为什么最好将其转换为ZonedDateTime之类的数据类型,以使排序更可预测。
    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 );
    }