Parsing a Duration String in Kotlin

后端 未结 3 1887
终归单人心
终归单人心 2021-01-06 10:06

I\'m working on a Android application and I need to parse a duration string of this form \"00:00:00.000\" (Ex: \"00:00:38.47\" or \"00:03:27.11\").

My final goal is

3条回答
  •  旧巷少年郎
    2021-01-06 10:28

    java.time.Duration

    As shown in the linked questions there are several ways to do this. I am afraid that there isn’t one objectively best way.

    You should most probably use a Duration from java.time, the modern Java date and time API, for your duration.

    Unfortunately there isn’t a way to parse your string directly into a Duration. My preference is for modifying your string into ISO 8601 format, the format that the Duration class knows how to parse. I trust you to translate my Java code into even more beautiful Kotlin code.

        String timeString = "00:01:08.83";
        String isoDurationString = timeString
                .replaceFirst("(\\d+):(\\d{2}):(\\d{2}(?:\\.\\d+)?)", "PT$1H$2M$3S");
        Duration dur = Duration.parse(isoDurationString);
        System.out.println(dur);
    

    Output from this snippet is:

    PT1M8.83S

    The regular expression is powerful but hard to read. The round brackets denote groups that I want to keep in the modified string; I refer to them as $1 etc. in the replacement string. (?:\\.\\d+) is a non-capturing group, one that I don’t need to use in the replacement. The ? after the non-capturing group says that it needs not be there (so the expression matches just 00:01:08 as well).

    For a percentage there are some options again. Duration objects can be directly multiplied by 100 and since Java 9 divided by each other. Assuming that you are not yet on Java 9, I would probably make the calculation based on milliseconds or nanoseconds (rather than seconds with a fraction). For example:

        long totalMilliseconds = dur.toMillis();
        System.out.println(totalMilliseconds);
    

    68830

    However to answer your question here’s how I would convert to seconds in a float:

        float totalSeconds = ((float) dur.toNanos()) / TimeUnit.SECONDS.toNanos(1);
        System.out.println(totalSeconds);
    

    68.83

提交回复
热议问题