Conversion of hours, min, sec. Line by hour

I want to convert time in the following format to hours.

My input, which is a temporary format, might look like

1 hour 30 mins 20 secs 
2 hrs 10 mins 
45 mins 

      

whereas my output would be:

1.505
2.167
0.75

      

This is a clock.

I am currently doing this manually by parsing the input string 1 hour 30 mins 20 secs

, detecting if a word is present hour/hours/hrs/hr

, and then taking the previous digits - same for minutes and seconds. I am using a formula to convert minutes and seconds to hours manually.

Is there a built-in condition I can use in Java?

+3


source to share


3 answers


An alternative way would be to parse it as aDuration

, but first you need to change the format a bit. Something like:



String adjusted = input.replaceAll("\\s+(hour|hr)[s]\\s+", "H");
//Do the same for minutes and seconds
//So adjusted looks like 1H30M20S
Duration d = Duration.parse("PT" + adjusted);

double result = d.toMillis() / 3_600_000d;

      

+3


source


Normally I would not recommend Joda-Time (as it has been superseded by new Java APIs), but it is the only API I know with good formatting / parser for periods.

You can use a class PeriodFormatterBuilder

and use a method appendSuffix

to define suffixes for singular and multiple values ​​for each field:

import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;

// method to parse the period
public void getPeriod(String input) {
    PeriodFormatter formatter = new PeriodFormatterBuilder()
            // hours (singular and plural suffixes)
            .appendHours().appendSuffix("hour", "hours")
            // minutes
            .appendMinutes().appendSuffix("min", "mins")
            // seconds
            .appendSeconds().appendSuffix("sec", "secs")
            // create formatter
            .toFormatter();

    // remove spaces and change "hr" to "hour"
    Period p = formatter.parsePeriod(input.replaceAll(" ", "").replaceAll("hr", "hour")); 

    double hours = p.getHours();
    hours += p.getMinutes() / 60d;
    hours += p.getSeconds() / 3600d;
    System.out.println(hours);
}

// tests
getPeriod("1 hour 30 mins 20 secs");
getPeriod("2 hrs 10 mins");
getPeriod("45 mins");

      

Output:

+1.5055555555555555
2.1666666666666665
0.75


Another way to create it PeriodFormatter

is appendSuffix

with regular expressions. This is useful when you have many different options for the suffix (for example, hour

and hr

for the field hours):

PeriodFormatter formatter = new PeriodFormatterBuilder()
    // hours (all possible suffixes for singular and plural)
    .appendHours()
    .appendSuffix(
        // regular expressions for singular and plural
        new String[] { "^1$", ".*", "^1$", ".*" },
        // possible suffixes for singular and plural
        new String[] { " hour", " hours", " hr", " hrs" })
    // optional space (if there are more fields)
    .appendSeparatorIfFieldsBefore(" ")
    // minutes
    .appendMinutes().appendSuffix(" min", " mins")
    // optional space (if there are more fields)
    .appendSeparatorIfFieldsBefore(" ")
    // seconds
    .appendSeconds().appendSuffix(" sec", " secs")
    // create formatter
    .toFormatter();

      

Note that I also added appendSeparatorIfFieldsBefore(" ")

to indicate that it has a space before the next field.



The good thing about this version is that you don't need to preprocess the input:

// no need to call replaceAll (take input just as it is)
Period p = formatter.parsePeriod(input);

      

The output is the same as above.


Java 8 API with date

As @assylian's answer pointed out , you can use the class java.time.Duration

:

public void getDuration(String input) {
    // replace hour/min/secs strings for H, M and S
    String adjusted = input.replaceAll("\\s*(hour|hr)s?\\s*", "H");
    adjusted = adjusted.replaceAll("\\s*mins?\\s*", "M");
    adjusted = adjusted.replaceAll("\\s*secs?\\s*", "S");
    Duration d = Duration.parse("PT" + adjusted);

    double hours = d.toMillis() / 3600000d;
    System.out.println(hours);
}

//tests
getDuration("1 hour 30 mins 20 secs");
getDuration("2 hrs 10 mins");
getDuration("45 mins");

      

The conclusion is the same.

PS: if your Java version is <= 7 then you can use ThreeTen Backport . The class name and methods are the same, the only difference is the package name: org.threeten.bp

instead of java.time

.

+2


source


I am currently doing this:

private double convertToHours(String inputTime) {
    inputTime = " 1 hour 30 mins 20 secs";
    double hours = 0;
    List<String> timeList = Arrays.asList(inputTime.split(" "));
    ListIterator<String> iterator = timeList.listIterator();
    String time = null;
    String previous = null;
    while (iterator.hasNext()) {
        int prevIndex = iterator.previousIndex();
        time = (String) iterator.next();

        if (!time.isEmpty() && time != null) {

            if (time.contains("hours") || time.contains("hrs") || time.contains("hr") || time.contains("hour")) {
                // time = time.substring(0, time.indexOf('h'));
                    previous = timeList.get(prevIndex);

                hours = hours + Double.parseDouble(previous.trim());
            }

            if (time.contains("mins") || time.contains("min") || time.contains("mns")) {
                //time = time.substring(0, time.indexOf('m'));
                previous = timeList.get(prevIndex);
                hours = hours + Double.parseDouble(previous) / 60;
            }

            if (time.contains("secs") || time.contains("sec") || time.contains("scs")) {
                //time = time.substring(0, time.indexOf('s'));
                previous = timeList.get(prevIndex);
                hours = hours + Double.parseDouble(previous) / 3600;
            }
        }
    }
    return hours;
}

      

0


source







All Articles