Correct the Time-String in Java

The challenge

  • You have to create a method, that corrects a given time string.
  • There was a problem in addition, so many of the time strings are broken.
  • Time is formatted using the 24-hour clock, so from 00:00:00 to 23:59:59.

Examples

"09:10:01" -> "09:10:01"  
"11:70:10" -> "12:10:10"  
"19:99:99" -> "20:40:39"  
"24:01:01" -> "00:01:01"

The solution in Java code

Option 1:

public class Solution {
 public static String timeCorrect(String timestring) {
    if (timestring == null || !timestring.matches("^\\d{2}:\\d{2}:\\d{2}$")) {
      return null;
    }
    String[] split = timestring.split(":");
    int h = Integer.parseInt(split[0]);
    int m = Integer.parseInt(split[1]);
    int s = Integer.parseInt(split[2]);
    m += s / 60;
    s = s % 60;
    h += m / 60;
    m = m % 60;
    h = h % 24;
    return String.format("%02d:%02d:%02d", h, m, s);
  }
}

Option 2:

import static java.util.Arrays.stream;

class Solution {
  static String timeCorrect(String timestring) {
    if (timestring == null || !timestring.matches("\\d{2}:\\d{2}:\\d{2}")) return null;
    var units = stream(timestring.split(":")).mapToInt(Integer::parseInt).toArray();
    int sec = units[2] % 60;
    int min = (units[1] + units[2] / 60) % 60;
    int hours = (units[0] + (units[1] + units[2] / 60) / 60) % 24;
    return String.format("%02d:%02d:%02d", hours, min, sec);
  }
}

Option 3:

public class Solution {

    public static String timeCorrect(String timestring) {
        if (timestring == null || timestring.equals("")) return null;
        if (!timestring.matches("\\d{2}:\\d{2}:\\d{2}")) return null;

        String[] elements = timestring.split(":");

        int hour = Integer.parseInt(elements[0]);
        int min = Integer.parseInt(elements[1]);
        int sec = Integer.parseInt(elements[2]);

        min += sec / 60;
        sec = sec % 60;
        hour += min / 60;
        min = min % 60;
        hour = hour % 24;

        return String.format("%02d:%02d:%02d", hour, min, sec);
    }

}

Test cases to validate our solution

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;

public class SolutionTest {

    private void test(String expected, String input) {
        assertEquals(null, Solution.timeCorrect(null));
    }
    
    @Test
    public void testNull() {
        test(null, null);
    }

    @Test
    public void testEmpty() {
        test("", "");
    }
    
    @Test
    public void testCorrect() {
        Arrays.asList("09:10:01", "00:00:00", "23:59:59", "12:34:56")
        .forEach(s -> assertEquals(s, s));
    }
    
    @Test
    public void testCorrection() {
        assertEquals("12:10:10", Solution.timeCorrect("11:70:10"));
        assertEquals("20:39:09", Solution.timeCorrect("19:99:09"));
        assertEquals("20:40:39", Solution.timeCorrect("19:99:99"));
        assertEquals("00:01:01", Solution.timeCorrect("24:01:01"));
        assertEquals("04:01:01", Solution.timeCorrect("52:01:01"));
    }
    
    @Test
    public void testInvalidFormat() {
        assertEquals(null, Solution.timeCorrect("0:00:00"));
        assertEquals(null, Solution.timeCorrect("00:0:00"));
        assertEquals(null, Solution.timeCorrect("00:00:0"));
        assertEquals(null, Solution.timeCorrect("-0:00:00"));
        assertEquals(null, Solution.timeCorrect("00:00:000"));
        assertEquals(null, Solution.timeCorrect("000000"));
        assertEquals(null, Solution.timeCorrect("00;11;22"));
        assertEquals(null, Solution.timeCorrect("00:00:0/"));
        assertEquals(null, Solution.timeCorrect(":0:00:00"));
    }
    
    @Test
    public void testEdgeCases() {
        assertEquals("00:00:00", Solution.timeCorrect("24:00:00"));
        assertEquals("00:00:00", Solution.timeCorrect("23:59:60"));
        assertEquals("00:00:00", Solution.timeCorrect("47:59:60"));
        assertEquals("00:00:59", Solution.timeCorrect("47:60:59"));
        assertEquals("12:00:00", Solution.timeCorrect("12:00:00"));
        assertEquals("04:40:39", Solution.timeCorrect("99:99:99"));
        assertEquals("01:00:00", Solution.timeCorrect("24:60:00"));
        assertEquals("01:00:00", Solution.timeCorrect("25:00:00"));
    }
    
    @Test
    public void testRandom() {
        Random random = ThreadLocalRandom.current();
        for (int i = 0; i < 10_000; i++) {
            int h = random.nextInt(100);
            int m = random.nextInt(100);
            int s = random.nextInt(100);
            int cs = s;
            int cm = m + s / 60;
            int ch = h + cm / 60;
            cs %= 60;
            cm %= 60;
            ch %= 24;
            String input = String.format("%02d:%02d:%02d", h, m, s);
            String expectedOutput = String.format("%02d:%02d:%02d", ch, cm, cs);
            assertEquals(expectedOutput, Solution.timeCorrect(input));
        }
    }

}