--- Actually there is a much better way to do this, but if you want to use dates, skip the preliminary answer ---
Dates do not actually do what you want, which is apparently a calculation of time beyond the actual need to select time from the real world.
It will be much better for you to write your own class to avoid any unpleasant special treatment that the Dates must do to keep up with the Gregorian calendar. This special processing includes (but is not limited to) time zone information, daylight saving time, announced "missed days", leap seconds, leap years, etc.
public TimeOnly { private long timestamp; private int millis; private int seconds; ... etc ... public TimeOnly(int hours, int minutes, int seconds, int millis) { this.timestamp = millis + seconds * 1000L + minutes * 60000L + hours * 3600000L; this.millis = millis; this.seconds = seconds; ... etc ... } private TimeOnly(long timestamp) { this.timestamp = timestamp; this.millis = timestamp % 1000; this.seconds = timestamp % 60000L - this.millis; ... etc ... } public long getTimestamp() { return timestamp; } public int getMillis() { return millis; } public int getSeconds() { return seconds; } ... etc ... } public TimeFormatter { public TimeFormatter() { } public String format(Time time) { StringBuilder builder = new StringBuilder(); builder.append(String.valueOf(time.getHours())); builder.append(":"); builder.append(String.valueOf(time.getMinutes())); builder.append(":"); builder.append(String.valueOf(time.getSeconds())); builder.append("."); if (time.getMillis() < 10) { builder.append("00"); } else if (time.getMillis() < 100) { builder.append("0"); } builder.append(time.getMillis()); return builder.toString(); }
This decision may seem like he was inventing a wheel, but in fact he is avoiding using an octagon as a wheel. The behavior of the date is not what you want, although you could make Date work for some limited range of values.
If you want to get really fantasy, you could make the above tool comparable, etc. However, I would advise you not to do it. Do not provide update methods after the build, as this leads to some rather unpleasant recalculations and makes the code more difficult to maintain. Instead, provide methods that return new TimeOnlys in response to the operations you want to implement.
public TimeOnly addSeconds(int value) { int stamp = this.timestamp; stamp += value * 60000L; if (stamp < timestamp) { throw new Excepton("overflow"); } return new TimeOnly(stamp); }
Also, do not implement what you are not going to use. Unused code tends to be fertile ground for errors.
And, of course, a fallback for all โtemporaryโ things, consider using JodaTime, which distinguishes all of the different types of time measurements. However, for this small problem, it is similar to using a tank to destroy ant.
--- Preliminary answer ---
Without a full time specification (year, month, day, hour, minute, second, milliseconds), your time value formatted in the first step will have many fields that are not specified. What happens in these fields is likely to be garbage.
getTime() acts on the entire Date object, translating both valid fields and garbage into a value, where garbage can even change valid values โโ(96 sec = 1 minute and 36 seconds when the fields interact).
The best way to do this is to have all your โonly timeโ dates initialized to one known day, so when you perform comparisons and mathematical operations (is it, 3 11 23 > 1 02 10 ?), You get consistent results (yes, 3 11 23 > 1 02 10 , because actually it is 2013 02 10 00 03 11 23 > 2013 02 10 00 03 11 23 and not 2013 02 10 00 03 11 23 compared with 2000 02 10 00 03 11 23
When choosing a day to use, avoid the days adjacent to February 29, days that are approaching daylight saving time, etc.