Разница военного времени на Яве

Вот мой класс 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, а остаток преобразовал в часы и минуты. . А если я ввожу какие-то другие цифры, работает. Любая помощь приветствуется.

Одно решение: 1) принять входные данные в виде строки 2) отдельные часы и минуты и скрыть их в int, 3) рассчитать общее количество минут 4) снова преобразовать минуты в часы и минуты и вернуть

jrook 11.10.2018 20:40

в вашем примере: 240 => 2*60 + 40 = 160, 150 => 1*60 + 50 =110. Затем 160-110 = 50, что является правильным ответом

jrook 11.10.2018 20:42

@jrook Есть ли способ сделать это с целыми числами?

dynamitem 11.10.2018 20:44

да. Обычно у вас есть число от 0 до 2400, и вы хотите извлечь его цифры. Первые две цифры будут минутами, а последние две (если есть) часами. num % 100 будет минутами, а num / 100 будет часами.

jrook 11.10.2018 20:51

Также обратите внимание, что ваш чек не будет работать для таких номеров, как 1385. Вам нужно сначала извлечь часы и минуты и проверить их по отдельности.

jrook 11.10.2018 20:56

И просто подсказка: при тестировании кода не используйте сканер. Просто напишите код, который использует жестко запрограммированные значения. Нет необходимости, чтобы человек постоянно набирал одни и те же данные. Скорее напишите множество небольших методов тестирования, использующих конкретную точку данных, а затем напишите код, который проверяет соответствующие ожидаемые результаты. Другими словами: узнать о модульном тестировании можно еще и тдд.

GhostCat 11.10.2018 21:17

Совет по поводу терминов: в Соединенных Штатах это только «военное время». Для остального мира он просто известен как 24-часовые часы. en.wikipedia.org/wiki/24-hour_clock

Basil Bourque 12.10.2018 03:16

Обратите внимание, что по крайней мере одно из 000 или 2400 должно быть допустимым временем, поэтому выражение 2400> time> 0 означает, что вы никогда не можете указать полночь.

DavidW 15.10.2018 21:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
8
8
1 476
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Итак, чтобы вычислить время, прошедшее между двумя 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-часовом формате.

Вам нужно сначала проверить, больше ли один раз, чем другой, прежде чем вычитать, или вы можете получить отрицательный ответ из вышеперечисленного.

David Coler 11.10.2018 21:22

Ох, а также проверьте неправильный формат времени, который @jrook сказал в своем комментарии

David Coler 11.10.2018 21:44

Я признаю, что это не самое элегантное решение, но я также хотел, чтобы каждый, кто его увидел, мог легко прочитать код и понять, что он делает.

David Coler 11.10.2018 21:46

tl; dr

Duration
.between(
    LocalTime.parse( "0150" , DateTimeFormatter.ofPattern( "HHmm" ) ) ,
    LocalTime.parse( "0240" , DateTimeFormatter.ofPattern( "HHmm" ) ) 
)
.toString()

PT50M

Подробности

Возможно, вы просто делаете домашнее задание. Если да, укажите это в своем вопросе.

Но вы должны знать, что Java предоставляет классы для этой цели.

java.time

Современный подход использует классы 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.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?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11 и более поздние версии - часть стандартного Java API с объединенной реализацией.
    • В Java 9 добавлены некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP….

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и более.

Я очень ценю усилия, но мне нужно сделать это так, как упоминалось ранее, без использования дополнительных API. Спасибо!

dynamitem 16.10.2018 21:44
Ответ принят как подходящий

Я ответил на свой вопрос, решение заключалось в том, что я отделил часы от минутной части (например С 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 часов.

Другие вопросы по теме