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
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
.