// Copyright © 2016 HSL <https://www.hsl.fi> // This program is dual-licensed under the EUPL v1.2 and AGPLv3 licenses. package fi.hsl.parkandride.core.domain; import org.joda.time.LocalTime; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.google.common.base.Strings.isNullOrEmpty; import static java.lang.Integer.compare; public class Time extends Number implements Comparable<Time> { public static final int MAX = 24 * 60; // 1440 public static final Pattern PATTERN = Pattern.compile("(\\d?\\d)(?::(\\d\\d))?"); private final int time; public Time(int minutes) { if (minutes < 0 || minutes > MAX) { throw new IllegalArgumentException("Expected time between 00:00 (0) and 24:00 (1440)"); } this.time = minutes; } public Time(String time) { this(parseTime(time)); } public Time(LocalTime time) { this(60 * time.getHourOfDay() + time.getMinuteOfHour()); } public static int parseTime(String time) { if (isNullOrEmpty(time)) { throw new IllegalArgumentException("time should not be null or empty"); } Matcher m = PATTERN.matcher(time); if (m.matches()) { int hour = Integer.parseInt(m.group(1)); int minute = 0; String optionalMinute = m.group(2); if (optionalMinute != null) { minute = Integer.parseInt(optionalMinute); } if (hour > 24) { throw new IllegalArgumentException("hour should be <= 24"); } if (minute > 59) { throw new IllegalArgumentException("minute should be <= 59"); } return 60 * hour + minute; } else { throw new IllegalArgumentException("expected time in 24-h format, e.g. 9, 09, 24, 9:59, 23:01"); } } public int getHour() { return time / 60; } public int getMinute() { return time % 60; } public int getMinuteOfDay() { return time; } @Override public int hashCode() { return time; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } else if (obj instanceof Time) { Time other = (Time) obj; return this.time == other.time; } else { return false; } } @Override public int compareTo(Time other) { return compare(this.time, other.time); } @Override public String toString() { StringBuilder sb = new StringBuilder(5); append(getHour(), sb); int minute = getMinute(); if (minute > 0) { sb.append(':'); append(getMinute(), sb); } return sb.toString(); } private void append(int val, StringBuilder sb) { if (val < 10) { sb.append('0'); } sb.append(val); } public boolean isBefore(Time other) { return this.time < other.time; } public boolean isAfter(Time other) { return this.time > other.time; } @Override public int intValue() { return time; } @Override public long longValue() { return time; } @Override public float floatValue() { return time; } @Override public double doubleValue() { return time; } }