Вот мой класс TimeInterval:
public class TimeInterval {
private int fTime;
private int sTime;
public TimeInterval(int fTime, int sTime) {
if (fTime < 0 || fTime > 2400 || sTime < 0 || sTime > 2400) {
System.out.println("Illegal times, must be < 2400 and > 0)");
System.exit(0);
} else {
this.fTime = fTime;
this.sTime = sTime;
}
}
public int getHours() {
return Math.abs((fTime - sTime) / 100);
}
public int getMinutes() {
return Math.abs((fTime - sTime) % 100);
}
public double getDecimalTime() {
return getHours() + ((double) getMinutes() / 60);
}
}
и мой класс тестера:
import java.util.*;
public class TestTimeInterval {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Please enter the first time: ");
int fTime = s.nextInt();
System.out.print("Please enter the second time: ");
int sTime = s.nextInt();
TimeInterval t = new TimeInterval(fTime, sTime);
System.out.printf("%s: %2d hours %2d minutes \n", "Elapsed time in hrs/min ", t.getHours(), t.getMinutes());
System.out.printf("%s: %.2f", "Elapsed time in decimal", t.getDecimalTime());
}
}
Тем не менее, он вычисляет определенное время правильно, но если я ввожу, например, 0150 и 0240, разница должна быть 50 минут, но вместо этого отображается 90, и мне нужно сделать так, чтобы оно не превышало 60, а остаток преобразовал в часы и минуты. . А если я ввожу какие-то другие цифры, работает. Любая помощь приветствуется.
в вашем примере: 240 => 2*60 + 40 = 160, 150 => 1*60 + 50 =110. Затем 160-110 = 50, что является правильным ответом
@jrook Есть ли способ сделать это с целыми числами?
да. Обычно у вас есть число от 0 до 2400, и вы хотите извлечь его цифры. Первые две цифры будут минутами, а последние две (если есть) часами. num % 100 будет минутами, а num / 100 будет часами.
Также обратите внимание, что ваш чек не будет работать для таких номеров, как 1385. Вам нужно сначала извлечь часы и минуты и проверить их по отдельности.
И просто подсказка: при тестировании кода не используйте сканер. Просто напишите код, который использует жестко запрограммированные значения. Нет необходимости, чтобы человек постоянно набирал одни и те же данные. Скорее напишите множество небольших методов тестирования, использующих конкретную точку данных, а затем напишите код, который проверяет соответствующие ожидаемые результаты. Другими словами: узнать о модульном тестировании можно еще и тдд.
Совет по поводу терминов: в Соединенных Штатах это только «военное время». Для остального мира он просто известен как 24-часовые часы. en.wikipedia.org/wiki/24-hour_clock
Обратите внимание, что по крайней мере одно из 000 или 2400 должно быть допустимым временем, поэтому выражение 2400> time> 0 означает, что вы никогда не можете указать полночь.




Итак, чтобы вычислить время, прошедшее между двумя 24-часовыми временами, вам нужно перевести в общее количество минут, теперь используемые вами функции по модулю не будут работать, так как 1 час = 60 минут, а не 100 минут.
Итак, сначала переведем все часы / менуэты в минутное время.
int ftminuets = 0;
int stminuets = 0;
int totalmin = 0;
int elapsed = = 0
while(fTime >= 100)
{
ftminuets += 60;
fTime -= 100;
}
ftminuets += fTime; //gets remaining minuets from fTime.
while(sTime >= 100)
{
stminuets += 60;
sTime -= 100;
}
stminuets += sTime; //gets remaining minuets from sTime.
//time to subtract
totalmin = stminuets - ftminuets;
//now total min has the total minuets in what can be considered to be 60 min increments. Now just to switch it back into a 24 hours time.
while(totalmin >= 60)
{
elapsed += 100;
totalmin -= 60;
}
elapsed += totalmin; //get rest of the minuets.
elapsed теперь должно отображать прошедшее время в 24-часовом формате.
Вам нужно сначала проверить, больше ли один раз, чем другой, прежде чем вычитать, или вы можете получить отрицательный ответ из вышеперечисленного.
Ох, а также проверьте неправильный формат времени, который @jrook сказал в своем комментарии
Я признаю, что это не самое элегантное решение, но я также хотел, чтобы каждый, кто его увидел, мог легко прочитать код и понять, что он делает.
Duration
.between(
LocalTime.parse( "0150" , DateTimeFormatter.ofPattern( "HHmm" ) ) ,
LocalTime.parse( "0240" , DateTimeFormatter.ofPattern( "HHmm" ) )
)
.toString()
PT50M
Возможно, вы просто делаете домашнее задание. Если да, укажите это в своем вопросе.
Но вы должны знать, что Java предоставляет классы для этой цели.
Современный подход использует классы java.time. По умолчанию эти классы работают в 24-часовом формате.
LocalTimeДля времени суток без даты и без часового пояса используйте LocalTime.
LocalTime start = LocalTime.of( 1 , 50 );
LocalTime stop = LocalTime.of( 2 , 40 );
DurationРассчитайте прошедшее время как Duration.
Duration d = Duration.between( start , stop );
Сгенерируйте текст, представляющий это значение Duration. По умолчанию используется стандартный формат ISO 8601.
System.out.println( d );
PT50M
При желании можно извлечь детали.
int hours = d.toHoursPart() ;
int minutes = d.toMinutesPart() ;
Чтобы проанализировать ваш формат ЧЧММ, предоставленный вашими пользователями, используйте DateTimeFormatter.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "HHmm" ) ;
LocalTime lt = LocalTime.parse( "0150" , f ) ;
Имейте в виду, что работа только с временем дня без контекста даты и часового пояса может привести к неверным результатам. Если работаешь в UTC, проблем нет. Но если ваши значения времени суток на самом деле предназначены для представления времени на настенных часах определенного региона, то такие аномалии, как переход на летнее время (DST), будут игнорироваться при использовании только LocalTime. В вашем примере может не быть двух часов или два часа были повторены, если это происходит в дату перехода на летнее время в Соединенных Штатах.
Если вы неявно указали часовой пояс, сделайте это явным, применив ZoneId для получения объекта ZonedDateTime.
LocalDate ld = LocalDate.of( 2018 , 1 , 23 ) ;
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
…
Duration d = Duration.between( zdt , laterZdt ) ;
Фреймворк java.time встроен в Java 8 и новее. Эти классы заменяют неудобные старые классы даты и времени наследие, такие как java.util.Date, Calendar, & SimpleDateFormat.
Проект Джода-Тайм, теперь в Режим технического обслуживания, советует перейти на классы java.time.
Чтобы узнать больше, см. Учебник Oracle. И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте Драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в классах java.sql.*.
Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и более.
Я очень ценю усилия, но мне нужно сделать это так, как упоминалось ранее, без использования дополнительных API. Спасибо!
Я ответил на свой вопрос, решение заключалось в том, что я отделил часы от минутной части (например С 1159 до 11 и 59), умножил часы, чтобы получить минуты, и добавил это к остальным минутам.
this.fTimeInMin = ((fTime / 100) * 60) + (fTime % 100);
this.sTimeInMin = ((sTime / 100) * 60) + (sTime % 100);
А затем в getHours() и getMinutes() метод преобразовал минуты в часы и минуты:
public int getHours() {
return Math.abs((this.fTimeInMin - this.sTimeInMin) / 60);
}
public int getMinutes() {
return Math.abs((this.fTimeInMin - this.sTimeInMin) % 60);
}
Что ж, это решение, которое вы ищете. Разделение времени в миллионах, чтобы вы могли получить часы и минуты отдельно, а остальное - просто вычисления. Единственное, что вы примете два параметра как строки.
public class TimeInterval {
private String fTime;
private String sTime;
private static int timeDiffMinutes;
public static void main(String[] args) {
String fTime = "0330";
String sTime = "1330";
TimeInterval t = new TimeInterval(fTime, sTime);
System.out.println("timeDiff " + getTimeDiffMinutes());
System.out.println(t.getHours() + "...." + t.getMinutes());
System.out.println(t.getDecimalTime());
}
public TimeInterval(String fTime, String sTime) {
int fTimeInt = Integer.valueOf(fTime);
int sTimeInt = Integer.valueOf(sTime);
if (fTimeInt < 0 || fTimeInt > 2400 || sTimeInt < 0 || sTimeInt > 2400) {
System.out.println("Illegal times, must be < 2400 and > 0)");
System.exit(0);
} else {
this.fTime = fTime;
this.sTime = sTime;
getTimeDiff();
}
}
public static int getTimeDiffMinutes() {
return timeDiffMinutes;
}
public int getHours() {
return Math.abs(timeDiffMinutes / 60);
}
public int getMinutes() {
return Math.abs(timeDiffMinutes);
}
public double getDecimalTime() {
return getHours() + ((double) getMinutes() / 60);
}
public void getTimeDiff() {
final int mid1 = fTime.length() / 2; //get the middle of the String
String[] parts = {fTime.substring(0, mid1), fTime.substring(mid1)};
String fPart = parts[0];
final int mid = sTime.length() / 2; //get the middle of the String
String[] sParts = {sTime.substring(0, mid), sTime.substring(mid)};
String sPart = sParts[0];
int toBeExcluded = (Integer.valueOf(sPart) - Integer.valueOf(fPart)) * 40;
this.timeDiffMinutes = (Integer.valueOf(sTime) - Integer.valueOf(fTime)) - toBeExcluded;
}
}
как вы проверяете, нет ли неправильной недействительной записи? это не обязательно? Если это так, ваш метод, даже если в настоящее время требуется менее 30 операций, вырастет до гораздо большего числа операций, что не включает проблемы 0000 часов или 2400 часов.
Одно решение: 1) принять входные данные в виде строки 2) отдельные часы и минуты и скрыть их в int, 3) рассчитать общее количество минут 4) снова преобразовать минуты в часы и минуты и вернуть