如何在Java中表示和操作大于24:00的时间值?
我目前正在一个应用程序域中做一些工作,它使用大于24:00的时间值来表示午夜后的时间,这些时间仍然与前一天的细节相关。例如,它可能使用星期一的25:15表示星期二的凌晨1:15,因为从域的角度来看,该值仍然与星期一的数据关联 维基百科的文章中简要提到了这种时间使用方式: 超过24:00的时间标记(例如24:01或25:00而不是00:01或01:00)不常用,也不在相关标准的范围内。然而,在[各个国家]的某些特殊情况下,它们偶尔会被用于工作时间超过午夜的场合,如广播电视制作和日程安排 Java提供了表示时间的模型类。但是,如何在Java中表示和操作大于24:00的时间值?,java,time,java-time,Java,Time,Java Time,我目前正在一个应用程序域中做一些工作,它使用大于24:00的时间值来表示午夜后的时间,这些时间仍然与前一天的细节相关。例如,它可能使用星期一的25:15表示星期二的凌晨1:15,因为从域的角度来看,该值仍然与星期一的数据关联 维基百科的文章中简要提到了这种时间使用方式: 超过24:00的时间标记(例如24:01或25:00而不是00:01或01:00)不常用,也不在相关标准的范围内。然而,在[各个国家]的某些特殊情况下,它们偶尔会被用于工作时间超过午夜的场合,如广播电视制作和日程安排 Java提
LocalTime
被限制在给定日期的午夜(含)和第二天的午夜(不含)之间,即在范围[0:00-23:59:59.9999999]
内
Java时间API是灵活编写的,但是核心API中排除了更专业的概念。正如Java 8日期与时间库的主要作者策划的项目中所述:
并非所有的日期/时间逻辑都是为JDK设计的。有些概念过于专业化或过于庞大,无法实现
我没有幸运地找到一个现有的类型或其他直接的方法来通过核心Java库或应用程序对这种时间约束较少的类型进行建模。然而,很有可能我遗漏了一些东西,也许是一些相当明显的东西
我如何在Java中对这种时间约束较小的模型进行建模,最好使用Java.time
API或ThreeTen Extra项目的扩展?我希望能够使用它以文本形式表示时间值(“25:15”),并理想地使用它执行时间计算(例如,将“星期一@25:15”转换为“星期二@1:15 AM”)
如果没有直接的方法,我可能会在Threeten Extra项目中打开一个问题。我的第一个想法是将其存储为对象。当您想要显示值时,可以很容易地使用该类上的getter来构造
HH:mm
字符串,或者使用类似apachecommons的东西
LocalDate
和LocalDateTime
类支持添加和减去持续时间等操作。No不存在
我确信三十家庭的任何一门课或其他地方的常用课都不能满足你的需要。我搜索到的最接近的是Time4J库的daycles
类(底部的链接)。它由一天中的一个时间(一个普通时间
)和一个与未指定日期相关的天数组成,因此您需要什么;但它专门用于返回从纯时间
中添加或减去时间的结果,并且不提供任何自己的功能
自作主张
我不认为开发您自己的可以与java.time互操作的类太难。根据更精确的需求,它可能以Mark B建议的java.time.Duration
为基础
如果您对解析和格式化有严格的要求,那么解析和格式化可能是最难的部分。也许值得从Joda时间库的源代码中汲取灵感,因为它包括格式化和解析持续时间的功能
另一个灵感来源是java.time.LocalTime
以下是最开始的几位:
public class SpecializedTime {
private Duration timeSince0000;
private SpecializedTime(Duration timeSince0000) {
this.timeSince0000 = timeSince0000;
}
static SpecializedTime parse(String text, DateTimeFormatter formatter) {
ParsePosition position = new ParsePosition(0);
TemporalAccessor parsed = formatter.parseUnresolved(text, position);
if (position.getErrorIndex() != -1) {
throw new DateTimeParseException("Parse error", text, position.getErrorIndex());
}
if (position.getIndex() != text.length()) {
throw new DateTimeParseException("Unparsed text", text, position.getIndex());
}
if (! parsed.isSupported(ChronoField.HOUR_OF_DAY)) {
throw new DateTimeParseException("Cannot resolve", text, 0);
}
Duration time = Duration.ofHours(parsed.getLong(ChronoField.HOUR_OF_DAY));
if (parsed.isSupported(ChronoField.MINUTE_OF_HOUR)) {
int minuteOfHour = parsed.get(ChronoField.MINUTE_OF_HOUR);
// Should validate, 0..59
time = time.plusMinutes(minuteOfHour);
}
// Same for seconds and nanoseconds
return new SpecializedTime(time);
}
@Override
public String toString() {
return String.format("%02d:%02d", timeSince0000.toHours(), timeSince0000.toMinutesPart());
}
}
演示:
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("H:m");
SpecializedTime st = SpecializedTime.parse("25:15", timeFormatter);
System.out.println(st);
输出:
25:15
链接
从Time4J来看,目前还没有一种类型可以在ThreeTen Extra或核心Java库中直接对这个概念建模。但是,现在有一个功能请求存在于请求此功能()的三个额外请求中 另外三名项目维护人员Stephen Colebourne表示,这将是对库的合理添加,因此,似乎主要取决于何时或是否有人来实现该功能 Stephen Colebourne还提出了一些在库中实现此功能的方法。这些建议的方法之一可以作为这个问题的定制解决方案的一部分 它可以是
LocalTime
和天数的组合,或者是更接近LocalTime
的组合。各种设计选项
我清楚地看到有必要。我曾经在开发一个公交时刻表系统。我们在一天中的0:00到36:00有自己的课程,精确到1分钟,因为夜班巴士通常被计划作为前一天时间表的一部分(我从未见过它用于凌晨4点(28:00)之后的时间,而是将范围设置得太大而不是太小)。显然,我们像平时一样有打印功能。当公共汽车在23:58发车,在0:03到达下一站时,他们理解,时刻表用户不需要进一步解释。只有在内部我们需要区分。