Poliquin
Poliquin

Reputation: 2987

Interval Time subtraction in Java

I was trying to find the difference in time (HH:mm:ss.SSS) in Java, where each time can be more than 24 hours. SimpleDateFormat does not support time which is greater than 24 hours.

For example,

Time A = 36:00:00.00
Time B = 23:00:00.00

I would like to get the answer of 13:00:00.00. (13 hours).

Does any one know whether there are any Java libraries that can perform the subtraction. Also would like to know whether time addition is possible with the Java library.

Upvotes: 5

Views: 8838

Answers (5)

user177800
user177800

Reputation:

You don't need a third party library

This is simple math, and doesn't directly appear to have anything to do with Date DateTime or Timestamp instances, but does appear to be interval related, and there is built in functionality into the JDK >= 1.5 with java.util.concurrent.TimeUnit to handle just this type of math without introducing any dependencies.

Here is the code to parse your input and convert it into milliseconds, which you can then convert back into whatever String format you want, I conveniently chose the format you requested.

java.util.concurrent.TimeUnit is a little hidden gem that most people don't know about that kind of snuck in to 1.5. It is kind of criminal that this class is buried in the java.util.concurrent package and no one seems to know about it.

import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main
{
    private static long parseInterval(final String s)
    {
        final Pattern p = Pattern.compile("^(\\d{2}):(\\d{2}):(\\d{2})\\.(\\d{3})$");
        final Matcher m = p.matcher(s);
        if (m.matches())
        {
            final long hr = Long.parseLong(m.group(1)) * TimeUnit.HOURS.toMillis(1);
            final long min = Long.parseLong(m.group(2)) * TimeUnit.MINUTES.toMillis(1);
            final long sec = Long.parseLong(m.group(3)) * TimeUnit.SECONDS.toMillis(1);
            final long ms = Long.parseLong(m.group(4));
            return hr + min + sec + ms;
        }
        else
        {
            throw new IllegalArgumentException(s + " is not a supported interval format!");
        }
    }

    private static String formatInterval(final long l)
    {
        final long hr = TimeUnit.MILLISECONDS.toHours(l);
        final long min = TimeUnit.MILLISECONDS.toMinutes(l - TimeUnit.HOURS.toMillis(hr));
        final long sec = TimeUnit.MILLISECONDS.toSeconds(l - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min));
        final long ms = TimeUnit.MILLISECONDS.toMillis(l - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min) - TimeUnit.SECONDS.toMillis(sec));
        return String.format("%02d:%02d:%02d.%03d", hr, min, sec, ms);
    }

    public static void main(final String[] args)
    {
        final String s1 = "36:00:00.000";
        final String s2 = "23:00:00.000";

        final long i1 = parseInterval(s1);
        final long i2 = parseInterval(s2);

        System.out.println(formatInterval(i1 - i2));
    }
}

the output is

13:00:00.000

I assume you meant for the last number to be milliseconds which should have a resolution of 3 digits.

Upvotes: 11

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 298898

Here's a complete solution using JodaTime. I dare say there's no comparably easy and elegant way to do it using java.util or java.util.concurrent apis:

public static int getHoursBetween(final String date1, final String date2){
    final DateTimeFormatter fmt =
        DateTimeFormat
            .forPattern("HH:mm:ss.SS")
            .withChronology(
                LenientChronology.getInstance(
                    GregorianChronology.getInstance()));
    return Hours.hoursBetween(
        fmt.parseDateTime(date1),
        fmt.parseDateTime(date2)
    ).getHours();
}

(LenientChronology makes sure that values like 38:00:00.00 are supported)

Upvotes: 3

bamana
bamana

Reputation: 1625

Here is a sample of how to get the difference between two Dates using Joda-Time (which was mentioned by Jim Garrison earlier. It really is one of the best Time libraries available.

  public static void main(String[] args) {
    DateTime timeA = new DateTime(2011, 6, 13, 12, 0, 0, 0);
    DateTime timeB = new DateTime(2011, 6, 12, 23, 0, 0, 0);

    Period period = new Period(timeB, timeA);
    System.out.println(period.getHours());
  }

Upvotes: 0

Jim Garrison
Jim Garrison

Reputation: 86774

Take a look at Joda-Time, which is a complete library for dealing with times and dates in Java, including arithmetic on intervals.

Upvotes: 1

Mike V
Mike V

Reputation: 11

Try converting time to seconds, subtract then convert back to simple time format.

Upvotes: 0

Related Questions