Home > Net >  Parse to LocalTime pattern mm:ss.S
Parse to LocalTime pattern mm:ss.S

Time:11-02

How can parse LocalTime from String e.g. "10:38.0" in mm:ss.S format. I struggle to change the format.

    public static LocalTime parseTime(String time) {
        return localTime = LocalTime.parse(time, DateTimeFormatter.ofPattern("mm:ss.S"));
    }

Getting error

ISO of type java.time.format.Parsed java.time.format.DateTimeParseException: Text '10:38.2' could not be parsed: Unable to obtain LocalTime from TemporalAccessor: {MinuteOfHour=10, MicroOfSecond=200000, MilliOfSecond=200, NanoOfSecond=200000000, SecondOfMinute=38},

CodePudding user response:

The problem is, mm:ss isn't really a local time. It's more like a sprint race time. The error occurs because the translation demands a value for # of hours passed, and none are available ('no hours' is interpreted here as: They weren't in the pattern, not: "They were missing, therefore lets assume there are 0 hours").

One hacky way to fix that is to change your pattern to [HH:]mm:ss - the [] indicates optional input. Now the meaning changes: just 10:20 is interpreted as (via the optional input aspect) a shorthand for 00:10:20 and that is parsable into a LocalTime.

But, perhaps LocalTime isn't quite what you're looking for here; if indeed this describes the time passed to measure an event, you're looking for Duration, not LocalTime. Unfortunately, parsing 10:20 into a duration of 10 minutes and 20 seconds is non-trivial, the API just doesn't support it (only way to get there from a DTFormatter object is via LocalTime, crazily enough).

CodePudding user response:

I believe you want: .ofPattern("H:mm.s")

        public static LocalTime parseTime(String time) {
        return LocalTime.parse(time, DateTimeFormatter.ofPattern("H:mm.s"));
    }

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

CodePudding user response:

DateTimeFormatterBuilder#parseDefaulting

You can use DateTimeFormatterBuilder#parseDefaulting to default the hour of the day to zero.

However, in common sense, 10:38.0 represents a duration. You can obtain a Duration object by finding the duration between the parsed LocalTime and LocalTime.MIN.

Demo:

import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String str = "10:38.0";
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                                .appendPattern("mm:ss.S")
                                .toFormatter(Locale.ENGLISH);

        LocalTime time = LocalTime.parse(str, dtf);
        System.out.println(time);

        Duration duration = Duration.between(time, LocalTime.MIN);
        System.out.println(duration);
    }
}

Output:

00:10:38
PT-10M-38S

ONLINE DEMO

Learn more about the modern Date-Time API* from Trail: Date Time.


* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8 APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time.

  • Related