Math.min军事时间vs基地8



我正在制作一个程序,旨在通过军事时间获取经过的时间,这就是我迄今为止得到的:

public class TimeInterval {
private int firstTime;
private int secondTime;
public TimeInterval(int _first,int _second) {
if (_first < 0 || _second < 0) {
System.out.println("ERROR INVALID INPUT");
System.exit(0);
}
else if (_first > 2400 || _second > 2400) {
System.out.println("ERROR INVALID INPUT");
System.exit(0); 
}
else
firstTime = Math.max(_first, _second);
secondTime = Math.min(_first,_second);
}
}
public int getHours() {
return (Integer.parseInt(Integer.toString(firstTime).substring(0, 2)))-(Integer.parseInt(Integer.toString(secondTime).substring(0, 2)));
}
}

除了处理从0000到0700的_first或_second输入外,该程序在大部分情况下都能工作。其想法是,它们被读取为军事时间,但java将它们读取为基数为8的整数,因此当_first=0700和_second=1400时,我得到448或其他值。不管怎样,我可以确保当_first和_second被输入Math.min时,它们被读取为基数10而不是基数8。

您似乎假设军事时间总是4位数,并带有适当数量的前导零,从0000到2359。你不能用int来表示军事时间的概念,因为int不一定有4位数。相同的数字可以格式化为6、06、006、0006或000000006。在内部,它只是相同的32位。因此,当firstTime为700(或0700(时,则Integer.toString(firstTime).substring(0, 2))取700的前两位,并得出70(而不是7(。因此new TimeInterval(700, 1400).getHours()的产率为-56(而不是7(。如果firstTime小于或等于9(0009(,您的代码可能会因StringIndexOutOfBoundsException而崩溃。

一个解决方案是在长度为4的String中度过你的军事时间。然后,您的子字符串操作将始终使用前两位数字,即小时。如果你坚持使用int,另一个解决方案是用模100运算来获得小时数:firstTime % 100

你提到了碱基8,也称为八进制。您显示的代码中没有任何内容会导致使用base8。当然,如果您使用类似new TimeInterval(0700, 1400)的类,那么Java将需要0700作为基数8,所以448,您是正确的。在这种情况下,你得到的小时数将是14-44=-30。再次传递字符串将解决此问题。

深入挖掘并找到一个好的解决方案

我想进一步建议:

  • 当时间为1059和1202时,它们之间有1小时3分钟。在这种情况下,你不希望时间是1而不是2吗
  • 使用java.time的LocalTime类,即现代的java日期和时间API,作为您一天中的时间。当您在某些界面中使用军事工时时,请将其保留在界面中,无论是String还是int形式,或者两者都是。在构建TimeInterval实例时进行正确的转换

所以你的类可能会变成:

public class TimeInterval{
private static final DateTimeFormatter FORMATTER_FOR_MILITARY_HOURS
= DateTimeFormatter.ofPattern("HHmm");

private LocalTime firstTime;
private LocalTime secondTime;
/** Main constructor */
public TimeInterval(LocalTime firstTime, LocalTime secondTime){
if (firstTime.isAfter(secondTime)) {
// Switch around
this.firstTime = secondTime;
this.secondTime = firstTime;
} else {
this.firstTime = firstTime;
this.secondTime = secondTime;
}
}
/** Convenience constructor accepting military hours */
public TimeInterval(String first, String last) {
this(LocalTime.parse(first, FORMATTER_FOR_MILITARY_HOURS),
LocalTime.parse(last, FORMATTER_FOR_MILITARY_HOURS));
}
public int getHours(){
long differenceInHours = ChronoUnit.HOURS.between(firstTime, secondTime);
return Math.toIntExact(differenceInHours);
}
}

这也为我们提供了一个免费的范围检查:LocalTime只处理00:00到23:59:59.9999999999的时间。因此,在这个范围外经过时间会引发异常(抱歉,2400无法处理(。如果字符串的格式不正确,也会发生同样的情况,比如长度不是4或分钟大于59。

方便构造函数中的this()是对另一个构造函数的调用,该构造函数接受LocalTIme作为参数。

ChronoUnit.between()返回一个长。由于我们知道最多可以有23个小时,我们可以安全地转换为intMath.toIntExact()为我们做到了这一点。

最新更新