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 standards 和 PT-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
我使用 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 standards 和 PT-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