---实际上有一个更好的方法可以做到这一点,但如果你想使用日期,请跳到预编辑答案---
日期实际上并没有按照您的意愿行事,这似乎是在实际需要从现实世界日历中挑选时间之外的时间计算。
你最好编写自己的类,以避免 Dates 为了跟上公历而必须做的所有讨厌的特殊处理。这种特殊处理包括(但不限于)时区意识、夏令时、声明的“跳过的日子”、闰秒、闰年等。
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();
}
这个解决方案看起来像是在重新发明轮子,但实际上它是在避免使用八角形作为轮子。Date 的行为似乎不是您想要的,尽管您可以使 Date 适用于某些有限的值范围。
如果您想变得真正花哨,可以使上述工具具有可比性,等等。但是,我建议不要这样做。不要在构造后提供更新方法,因为这会强制进行一些非常讨厌的重新计算并使代码更难维护。而是提供返回新 TimeOnlys 以响应您希望实现的操作的方法。
public TimeOnly addSeconds(int value) {
int stamp = this.timestamp;
stamp += value * 60000L;
if (stamp < timestamp) {
throw new Excepton("overflow");
}
return new TimeOnly(stamp);
}
另外,不要实现你不会使用的东西。未使用的代码往往是滋生错误的沃土。
当然,所有“时间”事物的标准答案,考虑使用 JodaTime,它区分所有不同类型的时间测量。但是,对于这样一个小问题,它类似于使用坦克杀死一只蚂蚁。
---预编辑答案---
如果没有完整的时间规范(年、月、日、小时、分钟、秒、毫秒),您在第一步中格式化的时间值将有很多未指定的字段。这些领域的内容很可能是垃圾。
然后getTime()
作用于整个Date
对象,将有效字段和垃圾转换为一个值,其中垃圾甚至可以修改有效值(96 秒 = 1 分 36 秒,因为字段交互)。
解决此问题的最佳方法是将所有“仅时间”日期初始化为一个已知日期,因此当您进行比较和数学运算(是,3 11 23
> 1 02 10
?)时,您会得到一致的结果(是的,3 11 23
> 1 02 10
,因为它实际上是2013 02 10 00 03 11 23
>2013 02 10 00 03 11 23
而不是2013 02 10 00 03 11 23
比较2000 02 10 00 03 11 23
选择使用日期时,请避开 2 月 29 日附近的日子、接近夏令时的日子等。