How can I represent and operate on time values greater than 24:00 in Java?

拜拜、爱过 提交于 2021-02-05 05:36:10

问题


I'm currently doing some work in an application domain that uses time values greater than 24:00 to represent times after midnight that are still associated with the previous day's details. For instance, it might use 25:15 on Monday to represent 1:15 AM on Tuesday, since from a domain standpoint, this value is still associated with Monday's data.

This type of time usage is briefly mentioned in the Wikipedia article for the 24-hour clock:

Time-of-day notations beyond 24:00 (such as 24:01 or 25:00 instead of 00:01 or 01:00) are not commonly used and not covered by the relevant standards. However, they have been used occasionally in some special contexts in [various countries] where business hours extend beyond midnight, such as broadcast television production and scheduling.

Java provides the LocalTime model class to represent times. However, LocalTime is constrained to be between midnight of the given day (inclusive) and midnight the next day (exclusive), i.e. in the range [0:00-23:59:59.999999999].

The Java Time API was written to be flexible, but with more specialized concepts excluded from the core API. As mentioned in the ThreeTen Extra project curated by the primary author of the Java 8 date & time library:

Not every piece of date/time logic is destined for the JDK. Some concepts are too specialized or too bulky to make it in.

I have not had luck finding an existing type or other straightforward way to model this less-constrained time type through the core Java libraries or ThreeTen Extra. It is however, very possible that I'm missing something, perhaps something fairly obvious.

How can I model this sort of less-constrained time in Java, ideally using the java.time API or an extension thereof a la the ThreeTen-Extra project? I would like to be able to use it to textually represent the time value ("25:15") and ideally perform temporal calculations with it (e.g. convert "Monday @ 25:15" to "Tuesday @ 1:15 AM").

If there isn't a straightforward approach, I'll probably end up opening an issue at the Threeten-Extra project.


回答1:


My first thought is to store that as a Duration object. You could easily use the getters on that class to construct the HH:mm string when you want to display the value, or use something like the Apache Commons DurationFormatUtils.

The LocalDate and LocalDateTime classes support operations like adding and subtracting Durations.




回答2:


No that does not exist

I am convinced that no class in the three-ten family or commonly used class from elsewhere supports what you want. The closest my search could get was the DayCycles class of the Time4J library (link at the bottom). It consists of a time of day (a PlainTime) and a count of days relative to an unspecified date, so what you ask for; but it’s specifically for returning the result of adding or subtracting time from a PlainTime and doesn’t offer any functionality of its own.

Spin your own

I wouldn’t think that developing your own class that could interoperate with java.time would be too hard. Likely base it off java.time.Duration as Mark B suggests, depending on more precise requirements.

Parsing and formatting may be the hardest part if you have demanding requirements for these. Possibly it’s worth taking inspiration from the source code for the Joda-Time library since this includes facilities for formatting and parsing durations.

Another source of inspiration would be the source of java.time.LocalTime.

Here are the very first few bits:

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());
    }

}

Demonstration:

        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("H:m");
        SpecializedTime st = SpecializedTime.parse("25:15", timeFormatter);
        System.out.println(st);

Output:

25:15

Link

Documentation of DayCycles form Time4J



来源:https://stackoverflow.com/questions/65484152/how-can-i-represent-and-operate-on-time-values-greater-than-2400-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!