Java 从一天到另一天的持续时间错误

Java Duration error from a day to another

我使用 Java 持续时间发现了一个非常简单的问题。

     LocalTime SaturdayStart = LocalTime.of(22, 30); 
     LocalTime SaturdayEnd = LocalTime.of(01, 00);
     System.out.println(SaturdayStart);
     System.out.println(SaturdayEnd);
     System.out.println(Duration.between(SaturdayStart, SaturdayEnd));

这段代码的输出是:

22:30
01:00
PT-21H-30M

这就是问题所在。我希望持续时间为 2H-30M,而不是 21H。是什么导致该方法无法在两次之间看到 "day change"?

请记住,LocalTime 仅代表一个时间,在 一个 天,没有时区。

因为它代表你在一天时钟上看到的时间,你不能用它来计算22:30今天之间的差异 和 01:00 第二天 。您的两个 LocalTime 对象分别代表 22:30 今天 和 01:00 今天

要考虑这一天,您需要 LocalDateTime。这不仅代表时间(没有时区),还代表 ISO-8601 日历系统中的日期。您可以像这样创建两个 LocalDateTime 对象:

LocalDateTime start = LocalDateTime.of(LocalDate.now(), LocalTime.of(22, 30));
LocalDateTime end = start.plusDays(1).withHour(1).withMinute(0);

然后可以得到时长:

Duration d = Duration.between(start, end);
System.out.println(d);

顺便说一下,您在错误输出中得到的 - 个字符不是不同组件的分隔符。它们是负号。这是因为你从01:00中减去22:30,这就像从一个较小的数中减去一个较大的数,你得到一个负数。

返回的Duration区间有数据,StartTime是否出现在EndTime之后,可用于进一步处理;像这样

     LocalTime SaturdayStart = LocalTime.of(22, 30); 
     LocalTime SaturdayEnd = LocalTime.of(01, 00);
     System.out.println(SaturdayStart);
     System.out.println(SaturdayEnd);
     Duration interval = Duration.between(SaturdayStart, SaturdayEnd);
     interval = interval.isNegative() ? interval.plusDays(1) : interval;
     System.out.println(interval);

java.time.Duration is modelled on ISO-8601 standardsPT-21H-30M 表示持续 21 小时 30 分钟,其中减号表示结束时间早于开始时间。因此,除非您考虑带时间的日期并且表示日期和时间的类型是 LocalDateTime,否则您无法得到您想要的。您可以选择任何日期并将其与时间组合以获得 LocalDateTime.

对于任何给定的日期,如果开始时间晚于结束时间,则将结束日期时间重置为午夜,然后再加上一天,最后将其时间设置为结束时间。

获得持续时间后,您可以通过从中获取小时、分钟、秒等来创建格式化字符串。 Java-9 引入了一些更方便的方法,使它更容易。

演示:

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalTime startTime = LocalTime.of(22, 30);
        LocalTime endTime = LocalTime.of(01, 00);

        LocalDateTime startDateTime = today.atTime(startTime);
        LocalDateTime endDateTime = today.atTime(endTime);

        if (startDateTime.isAfter(endDateTime)) {
            endDateTime = endDateTime.with(LocalTime.MIN).plusDays(1).with(endTime);
        }

        Duration duration = Duration.between(startDateTime, endDateTime);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedDuration = String.format("%dH-%dM-%dS", duration.toHours(), duration.toMinutes() % 60,
                duration.toSeconds() % 60);
        System.out.println(formattedDuration);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedDuration = String.format("%dH-%dM-%dS", duration.toHoursPart(), duration.toMinutesPart(),
                duration.toSecondsPart());
        System.out.println(formattedDuration);
        // ##############################################################################
    }
}

输出:

PT2H30M
2H-30M-0S
2H-30M-0S