Search code examples
androidtimedate-arithmetic

Sum and difference beetwen hours in Java (over 24h)


I'm developing an Android App and I need to calculate some times (with Joda libs). I would like to know if exist a Java class who does this.

The cases that I would like to calculate (in example):

Case 1:

t1 = "13:40"
t2 = "12:30"
result = t1 + t2 --> 26:10

Case 2:

t1 = "13:40"
t2 = "12:30"
result = t1 - t2 --> 1:10

Case 2.1:

t1 = "13:40"
t2 = "14:00"
result = t1 - t2 --> -0:20

Thanks!! :)


Solution

  • Following JodaTime-code handles both inputs and result as temporal amounts, not points in time:

    CASE 1:

    PeriodFormatterBuilder builder = new PeriodFormatterBuilder();
    builder.minimumPrintedDigits(2);
    builder.printZeroAlways();
    builder.appendHours();
    builder.appendLiteral(":");
    builder.appendMinutes();
    PeriodFormatter pf = builder.toFormatter();
    
    Period period1 = pf.parsePeriod("13:40");
    Period period2 = pf.parsePeriod("12:30");
    Period total = period1.plus(period2);
    Period normalized = total.normalizedStandard(PeriodType.time());
    
    System.out.println("TOTAL PERIOD: " + total); // PT25H70M
    System.out.println("NORMALIZED PERIOD: " + normalized); // PT26H10M
    System.out.println("FORMATTED NORMALIZED PERIOD: " + pf.print(normalized)); // 26:10
    

    CASE 2 + 2.1:

    PeriodFormatterBuilder builder = new PeriodFormatterBuilder();
    builder.minimumPrintedDigits(2);
    builder.printZeroAlways();
    builder.appendHours();
    builder.appendLiteral(":");
    builder.appendMinutes();
    PeriodFormatter pf = builder.toFormatter();
    
    Period period1 = pf.parsePeriod("13:40");
    Period period2 = pf.parsePeriod("14:00");
    
    boolean negative = false;
    
    if (period1.toStandardDuration().isShorterThan(period2.toStandardDuration())) {
      Period tmp = period1;
      period1 = period2;
      period2 = tmp;
      negative = true;
    }
    
    Period total = period1.minus(period2);
    Period normalized = total.normalizedStandard(PeriodType.time());
    System.out.println("NORMALIZED PERIOD: " + (negative ? "-" : "") + normalized);
    System.out.println(
      "FORMATTED NORMALIZED PERIOD: " + (negative ? "-" : "") + pf.print(normalized)
    ); // -00:20
    

    Note that due to insufficient sign handling of JodaTime (which likes to print the sign not in front but midth inside period expression) some clunky workaround is necessary.