【问题标题】:How can I compare time of the day between Date objects in Java 8?如何比较 Java 8 中 Date 对象之间的时间?
【发布时间】:2018-10-26 21:59:21
【问题描述】:

给定两个包含小时和分钟的 Date 对象,我如何优雅地找出其中哪一个具有一天中最早的时间?

例如如果date109:00 处是2018-01-01,并且date208:00 处是2018-01-02,则根据此规范,date2 < date1

【问题讨论】:

  • 请尽量避免使用旧的java.util.Date 类。相反,您应该查看 java.time 包并选择最适合您的用例的类。
  • Date 不包含任何小时或分钟。它只包含一个 long 值,该值是自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数。
  • 不幸的是,我使用的 API 返回一个 java.util.Date,我无法更改它。肯定会发生一些转变吗?或者一种保持时间但将年/月/日重置为相同值的方法,然后使用before
  • 很遗憾这个问题被否决了,因为很难在网上找到答案。
  • @SalvatoreIovene 将Date 转换为Instant,将Instant 从UTC 调整为时区以获得ZonedDateTime,并从ZonedDateTime 中提取LocalTime,并进行比较LocalTime 对象,都是 Stack Overflow 上已经讨论过很多次的主题。

标签: java date


【解决方案1】:

如果之前转换了Date,可以使用compareTo-LocalTime的方法。

像这样转换(位于https://www.baeldung.com/java-date-to-localdate-and-localdatetime):

public static LocalTime convertToLocalTimeViaInstant(Date dateToConvert) {
    return dateToConvert.toInstant()
            .atZone(ZoneId.systemDefault())
            .toLocalTime();
}

然后像这样比较:

time1.compareTo(time2);

如果你想使用一种方法,你可以像这样使用转换:

public static int compareTimeOfDates(Date date1, Date date2) {
    return convertToLocalTimeViaInstant(date1).compareTo(convertToLocalTimeViaInstant(date2));
}

【讨论】:

  • @SalvatoreIovene 我认为这并没有错失重点。它将您的 Date 对象转换为您可以比较的 LocalTime 对象。唯一缺少的部分是生成的 LocalTime 对象可能具有非零秒或纳秒,但这无关紧要。
  • 在您的回答中,您的转换方式完全相同。如果你直接转换为 LocalTime 你可以直接使用这个类的 compareToMethod。
  • @SalvatoreIovene 如果您愿意,可以在 LocalTime 对象上调用 getHour() 和 getMinute() 访问器并进行比较。结果应该是一样的。
  • 您可以在比较之前对两个LocalTime 对象执行truncateTo(ChronoUnit.MINUTES)withSecond(0).withNano(0),如果您希望从比较中排除这些对象。
【解决方案2】:

您可以尝试执行以下操作:

boolean compareTime(Date date1, Date date2) {
    DateFormat df = new SimpleDateFormat("HHmm");
    int timeDate1 = Integer.valueOf(df.format(date1));
    int timeDate2 = Integer.valueOf(df.format(date2));
    return timeDate1 >= timeDate2;
}

【讨论】:

  • 仅供参考,非常麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle
  • @Basil Bourque - topicstarter 在其中一个 cmets 中提到 java.util.Date 是从第三方 API 返回的,他无法更改。
  • 使用添加到旧类的新方法进行转换:java.time.Date::toInstant() 然后调用Instant::atZone 并调用ZonedDateTime::toLocalTime
【解决方案3】:
int compareTimeOfDate(Date a, Date b) {
    LocalDateTime localA = a.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    int hourA = localA.getHour();
    int minuteA = localA.getMinute();

    LocalDateTime localB = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    int hourB = localB.getHour();
    int minuteB = localB.getMinute();

    if (hourA == hourB && minuteA == minuteB) {
        return 0;
    }

    if (hour1 < hour2 || hour1 == hour2 && minute1 < minute2) {
        return -1;
    }

    return 1;
}

【讨论】:

  • 当你只想要LocalTime时,没有理由使用LocalDateTime
【解决方案4】:

编辑 2:

//just a sample. base on your case, set the date you have to here.
        Date date1 = Calendar.getInstance().getTime(); 
        Date date2 = Calendar.getInstance().getTime();

        LocalDateTime lcdate1 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime lcdate2 = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();


        int date1Hour = lcdate1.getHour();
        int date1Minute = lcdate1.getMinute();

        int date2Hour = lcdate2.getHour();
        int date2Minute = lcdate2.getMinute();

更多细节在这里:https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html

希望对您有所帮助。

【讨论】:

  • 谢谢,但缺少重要的部分,如何从原始 Date 中提取小时和分钟。
  • @SalvatoreIovene 只需编辑以获取小时和分钟。
  • @KennyTaiHuynh 是的,但是这些值是硬编码的,而不是来自原始 Date
  • @DavidConrad:好的,只要把转换和使用LocalDateTime的步骤(Java 8已经支持)。
  • LocalDateTime 是错误的类,因为它不能代表时刻,缺少时区或与 UTC 的偏移量。丢弃有价值的区域/偏移信息无助于解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 2018-11-02
  • 2012-10-22
  • 2021-02-05
  • 1970-01-01
相关资源
最近更新 更多