Convert hours, mins, secs String to hours

660
June 06, 2017, at 08:44 AM

I want to convert a time in the below format into hours.

My input which is a time format could be anything like

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

whereas my output will be:

1.505
2.167
0.75

These are the hours.

Currently I am doing it manually by parsing the input string 1 hour 30 mins 20 secs, finding whether the word hour/hours/hrs/hr is present, then taking the preceding digits--the same for mins and secs. I use the formula to convert mins and secs to hours manually.

Is there any built-in provision that I can use in Java?

Answer 1

An alternative way would be to parse it as a Duration, but you will need to change the format a bit first. 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;
Answer 2

Currently I'm doing like 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;
}
Answer 3

Usually I wouldn't recommend Joda-Time (as it's being replaced by the new Java API's), but it's the only API I know with a good formatter/parser for periods:

import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
// method to parse the period
public void void getPeriod(String input) {
    PeriodFormatter formatter = new PeriodFormatterBuilder()
            // hours
            .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

Java 8 date-time API

As stated in @assylian's answer, you can use the java.time.Duration class:

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 output is the same.

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

Rent Charter Buses Company
READ ALSO
Is it possible to use channels and buffers (java.nio) to read/write types of objects I created from/to a file?

Is it possible to use channels and buffers (java.nio) to read/write types of objects I created from/to a file?

I would like to know if it is possible to use channels and buffers (from javanio) to read/write types of objects I created from/to a file ?

551
Java database simulator to test query, How to write? [on hold]

Java database simulator to test query, How to write? [on hold]

In this problem, you will be given some table informationEvery table has a unique name and you can assume the name of each column of these tables are unique too

482
ReferenceContributor don&#39;t works for existing languages

ReferenceContributor don't works for existing languages

I am trying to implements a new reference from an existing language, in case, PHP, but it even is catched from debuggerSeems that it just is not initialized

481
Metadata to Liferay DLFolder in 6.2

Metadata to Liferay DLFolder in 6.2

I wrote a hook for Liferay 62's Documents and Media portlet that allows a user to apply a metadata to a DLFolder similar to how one would apply metadata to Document Type

450