0

I have different time formats in string (from videoplayer counter). For example:

03:45 -> 3 munutes, 45 seconds
1:03:45 -> 1 hour, 3 munutes, 45 seconds
123:03:45 -> 123 hours, 3 munutes, 45 seconds

How can I parse all this formats with LocalTime lib?

If I using such code:

LocalTime.parse(time, DateTimeFormatter.ofPattern("[H[H]:]mm:ss"));

It works fine for "1:03:45" or "11:03:45", but for "03:55" I have exception

java.time.format.DateTimeParseException: Text '03:55' could not be parsed at index 5
Ihar
  • 15
  • 1
  • 4
  • 3
    Probably just a side note: you're using the wrong data type for your value. `Duration` is a more appropriate type for these values. For example, you can't store `123:03:45` in a `localTime` object (`123` is out of range for hours) – ernest_k Mar 03 '19 at 16:15
  • 2
    123:03:45 is a duration not a local time. You could directly split on :'s and extract the hour, min, sec components. – CodeMonkey Mar 03 '19 at 16:16
  • Possible duplicate of [Converting Timestamp string “HH:mm:ss” to Duration](https://stackoverflow.com/questions/36292575/converting-timestamp-string-hhmmss-to-duration) – Ole V.V. Mar 03 '19 at 19:44
  • Hi @OleV.V. I don't think the OP ask for `HH:mm:ss` but any format of `mm:ss` and `HH:mm:ss`, I don't see any answer can answer this specific question – Youcef LAIDANI Mar 03 '19 at 19:52
  • thank you for your help! – Ihar Mar 06 '19 at 13:43

2 Answers2

1

There are more possibilities. I would probably go for modifying the time string to conform with the syntax accepted by Duration.parse.

    String[] timeStrings = { "03:45", "1:03:45", "123:03:45" };
    for (String timeString : timeStrings) {
        String modifiedString = timeString.replaceFirst("^(\\d+):(\\d{2}):(\\d{2})$", "PT$1H$2M$3S")
                .replaceFirst("^(\\d+):(\\d{2})$", "PT$1M$2S");
        System.out.println("Duration: " + Duration.parse(modifiedString));
    }

Output is:

Duration: PT3M45S
Duration: PT1H3M45S
Duration: PT123H3M45S

The case of hours, minutes and seconds (two colons) is handled by the first call to replaceFirst, which in turn removes both colons and makes sure that the second replaceFirst doesn’t replace anything. In the case of just one colon (minutes and seconds), the first replaceFirst cannot replcae anything and passes the string unchanged to the second replaceFirst call, which in turn transforms to the ISO 8601 format accepted by Duration.parse.

You need the Duration class for two reasons: (1) If I understand correctly, your time string denotes a duration, so using LocalTime is incorrect and will confuse those maintaining your code after you. (2) The maximum value of a LocalTime is 23:59:59.999999999, so it will never accept 123:03:45.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

From comments and what I read before, you can't parse mm:ss, to solve your issue lets convert all the times to seconds and then convert that seconds to a Duration and not to LocalTime, here is a solution for your problem :

String[] times = {"03:45", "1:03:45", "123:03:45"};
for (String time : times) {
    List<Integer> parts = Arrays.stream(time.split(":"))
            .map(Integer::valueOf)
            .collect(Collectors.toList());
    Collections.reverse(parts);

    int seconds = (int) IntStream.range(0, parts.size())
            .mapToDouble(index -> parts.get(index) * Math.pow(60, index))
            .sum();

    Duration result = Duration.ofSeconds(seconds);
    System.out.println(result);    
}

Outputs or duration is

PT3M45S              -> 03:45 
PT1H3M45S            -> 1:03:45  
PT123H3M45S          -> 123:03:45
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140