How to parse time in any format with LocalTime.parse?
Asked Answered
E

5

5

I am having trouble using java's LocalTime to parse a string with hours, minutes, and seconds.

LocalTime t = LocalTime.parse("8:30:17"); // Simplification

This throws the following exception:

Exception in thread "main" java.time.format.DateTimeParseException: Text '8:30:17' could not be parsed at index 0

Egalitarian answered 11/4, 2020 at 15:11 Comment(0)
P
6

You'll need to pass in a custom DateTimeFormatter like this:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H:mm:ss");
LocalTime t = LocalTime.parse(times.get(i), formatter);

Take a look at the docs, as the letters you need to use might be different.

Proponent answered 11/4, 2020 at 15:21 Comment(0)
H
6

The default formatter expects an ISO format, which uses 2 digits for each of the hours, minutes and seconds.

If you want to parse the time you showed, which only has one digit for hours, you will need to provide a custom formatter (note the single H):

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H:mm:ss");
LocalTime t = LocalTime.parse(times.get(i), formatter);
Halfpint answered 11/4, 2020 at 15:25 Comment(4)
Won't this break when it is, say, 10 o'clock?Proponent
No it won't (see the javadoc: "If the count of letters is one, then the value is output using the minimum number of digits and without padding.").Halfpint
Just tested it. Hey @Yuri, make this the accepted answer again, it's the correct one.Proponent
It’s a bit funny but very useful, @Schred: For numbers (including hour of day) one pattern letter does not mean one digit but rather as many digits as it takes. So it will parse 8, 08 and 10 happily. And print 8 or 10 (never 08).Fordone
L
1

You need to use DateTimeFormatter to give parser a format pattern to parse.

DateTimeFormatter formatter =DateTimeFormatter.ofPattern("H:mm:ss");
LocalTime t = LocalTime.parse(times.get(i), formatter);

Format Pattern Letters:

H       hour-of-day (0-23)
m       minute-of-hour
s       second-of-minute            
h       clock-hour-of-am-pm (1-12)
Ligroin answered 11/4, 2020 at 15:21 Comment(1)
@OleV.V. The interesting part is it the answer is accepted when it is HH:mm:ss this format. Check the edit history.Ligroin
U
1

From LocalTime.parse documentation :

The string must represent a valid time and is parsed using DateTimeFormatter.ISO_LOCAL_TIME.

According to the ISO_LOCAL_TIME documentation the condition for the hours is this:

Two digits for the hour-of-day. This is pre-padded by zero to ensure two digits.

You are parsing the value 8:30:17, one digit instead of two digits and so you are breaking the condition, causing the error.

Umbria answered 11/4, 2020 at 15:25 Comment(0)
U
0

By default, LocalTime#parse parses the input string using DateTimeFormatter.ISO_LOCAL_TIME whose format consists of:

  • Two digits for the hour-of-day. This is pre-padded by zero to ensure two digits.
  • A colon
  • Two digits for the minute-of-hour. This is pre-padded by zero to ensure two digits.
  • If the second-of-minute is not available then the format is complete.
  • A colon
  • Two digits for the second-of-minute. This is pre-padded by zero to ensure two digits.
  • If the nano-of-second is zero or not available then the format is complete.
  • A decimal point
  • One to nine digits for the nano-of-second. As many digits will be output as required.

Since your input string is not in this format, you have encountered the exception. You can get around the exception by using a DateTimeFormatter which allows you to specify a custom format. You can use H:m:s as the format.

Demo:

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:m:s", Locale.ENGLISH);
        LocalTime t = LocalTime.parse("8:30:17", dtf);
        System.out.println(t);
    }
}

Output:

08:30:17

ONLINE DEMO

Note that for formatting, the single letter, H works for single as well as a two-digit hour. Similar is the case with m and s as well.

Another thing you should always keep in mind is that the Date-Time formatting types are Locale-sensitive and therefore you should always specify the applicable Locale when using them. Check Never use SimpleDateFormat or DateTimeFormatter without a Locale to learn more about it.

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.

Uyekawa answered 8/10, 2021 at 21:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.