Как рассчитать разницу между двумя разами - PullRequest
0 голосов
/ 27 января 2019

Я хочу рассчитать время сна пользователя, он должен ввести, когда он спал, и когда он проснулся, и я должен рассчитать, сколько часов он спал

Например, если пользователь вводит

His sleeping time : 11:00 pm

His waking up time : 7:30 am

The number of sleeping hours should be : 8:30 hrs

Есть ли способ сделать этот расчет легко

Это код

cal.set(Calendar.HOUR_OF_DAY, 11);
        cal.set(Calendar.MINUTE, 0);
        sleepTimeOnOffDays = cal.getTime();

    private long subtractTwoDates(Date date1, Date date2) {

            Calendar calendar1 = Calendar.getInstance();
            Calendar calendar2 = Calendar.getInstance();
            calendar1.setTime(date1);
            calendar2.setTime(date2);
            long milsecs1 = calendar1.getTimeInMillis();
            long milsecs2 = calendar2.getTimeInMillis();
            long diff = milsecs2 - milsecs1;
            long dhours = diff / (60 * 60 * 1000);

            return Math.abs(dhours);
        }

Ответы [ 4 ]

0 голосов
/ 28 января 2019

tl; др

11: 00 вечера до 7:30 утра = 7,5 или 8,0 или 8,5 или 9,5 или другое количество часов в зависимости от конкретных дат и часового пояса.

Duration.between(
    ZonedDateTime.of( 2019 , 1 , 23 , 23 , 0 , 0 , 0 , ZoneId.of( "Africa/Cairo" ) ) ,
    ZonedDateTime.of( 2019 , 1 , 24 , 7 , 30 , 0 , 0 , ZoneId.of( "Africa/Cairo" ) )
)
.toString()

См. Этот код, запущенный в режиме реального времени на IdeOne.com .

PT8H30M

Для расчета истекшего времени требуется дата,время суток и часовой пояс

Ответ Маркуса Гензеля движется в правильном направлении, но не учитывает такие аномалии, как переход на летнее время (DST).

Ваш вопрос не совсем понятен.Вы хотите отследить общее представление о времени суток, используя обычные 24-часовые дни?Или вы хотите отслеживать реальные моменты, например, время, в которое спал два дня назад, время, в котором спал вчера, и так далее?

Если последнее, то вы не можете использовать LocalDateDate, так как этот класс по определению не может отслеживать моменты.В классе LocalDateTime отсутствует понятие часового пояса или смещения от UTC.Таким образом, LocalDateTime представляет потенциальных моментов в диапазоне около 26-27 часов (диапазон часовых поясов вокруг земного шара).

Учитывая ваш пример с 23:00 до 7:30, это будет означать 8,5 часов в определенном часовом поясе без аномалий на эту дату.Но в день перехода на летнее время это может означать 7,5 часов («весна впереди») или 9,5 часов («падение назад»).Или, может быть, 8,0 часов в день, например, в прошлом году, когда Северная Корея настроила свои часы на полчаса.Или когда в 2007 Венесуэла повернула время вспять на полчаса ... и затем десятилетие спустя снова перевернулась .Эти изменения происходят чаще, чем вы можете себе представить.Политики всего мира продемонстрировали склонность к пересмотру смещения их часового пояса.

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

ZoneId

Указать правильное имя часового пояса в формате Continent/Regionнапример America/Montreal, Africa/Casablanca или Pacific/Auckland.Никогда не используйте 2-4 буквенные сокращения, такие как EST или IST, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;

ZonedDateTime

Для отслеживания моментов используйте класс ZonedDateTime.Этот класс объединяет дату, время суток и часовой пояс.

LocalDate ldStart = LocalDate.of( 2019 , 1 , 23 ) ;
LocalTime ldStart = LocalTime.of( 23 , 0 ) ;
ZonedDateTime zdtStart = ZonedDateTime.of( ldStart , ltStart , z ) ;

И время остановки.

LocalDate ldStop = LocalDate.of( 2019 , 1 , 24 ) ;  // Next day.
LocalTime ldStop = LocalTime.of( 7 , 30 ) ;
ZonedDateTime zdtStop = ZonedDateTime.of( ldStop , ltStop , z ) ;

Рассчитать прошедшее время, используя Duration класс.

Duration d = Duration.between( zdtStart , zdtStop ) ;

ISO 8601

Iрекомендуем не сообщать прошедшее время, используя формат времени дня, ЧЧ: ММ: СС.Вместо этого используйте стандартный формат , определенный для этой цели , в стандарте ISO 8601 .

Таким образом, 8,5 часов будут PT8H30M.

Классы java.time используют форматы ISO 8601 по умолчанию при разборе / генерации строк.

String output = d.toString() ;  // Generate `PT8H30M`.

И разбор.

Duration d = Duration.parse( "PT8H30M" ) ;

О java.time

java.time Framework встроен в Java 8 и более поздние версии.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: 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) проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP адаптируется ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .

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

0 голосов
/ 27 января 2019

Просто попробуйте следующую строку кода, чтобы получить разницу в минутах

import java.util.concurrent.TimeUnit; // predefined method from java 6.

  private long subtractTwoDates(Date date1, Date date2) {
    Long diffInMinutes=null,diff=null;  // just  declaration of variables
    diff = date1.getTime() - date2.getTime();
    diffInMinutes= TimeUnit.MILLISECONDS.toMinutes(diff);
    log.info("diff min : "+difInMin); 
    return  diffInMinutes; // returns long value in minutes.
}
0 голосов
/ 27 января 2019

Начиная с Java SE 8, я хотел бы предложить использовать java.time API.Для пользователей Android java.time добавлен в API 26 + .

Java 8 представил новые API для даты и времени для устранения недостатков старых java.util.Date и java.util.Calendar.

Использование API java.time для вычисления длительности между двумя датами очень просто.

LocalDateTime localDateTime1 = LocalDateTime.now();
localDateTime1 = localDateTime1.withHour(23).withMinute(0).withSecond(0).withNano(0);

LocalDateTime localDateTime2 = LocalDateTime.now();
localDateTime2 = localDateTime2.plusDays(1).withHour(7).withMinute(30).withSecond(0).withNano(0);

Duration diff = Duration.between(localDateTime1, localDateTime2);

String hms = String.format("%d:%02d:%02d", 
                 diff.toHoursPart(),
                 diff.toMinutesPart(), 
                 diff.toSecondsPart());
System.out.println(hms);

-----------------------

Console output:
8:30:00

Если API java.time недоступен для вашего проекта, потому чтонапример, ваш проект еще не находится на уровне API 26, тогда я бы рекомендовал использовать ThreeTen Android Backport API, как предложено @Ole VV в комментариях ниже.

Синтаксис почти такой же, как и у java.time API.Приведенный выше фрагмент кода работает и для ThreeTen Android Backport API (как уже упоминалось @Basil Bourque), за одним исключением.К сожалению, класс Duration API-интерфейса ThreeTen Android Backport не предоставляет вспомогательных методов для извлечения части часов, минут и т. Д. Из объекта продолжительности.Вместо этого, когда вы используете бэкпорт, вам нужно сначала вычесть часы, а затем минуты из продолжительности, чтобы остались только секунды:

long hours = diff.toHours();
diff = diff.minusHours(hours);
long minutes = diff.toMinutes();
diff = diff.minusMinutes(minutes);
long seconds = diff.getSeconds();
String hms = String.format("%d:%02d:%02d", 
                 hours,
                 minutes, 
                 seconds);

Другое отличие заключается в том, что вам нужно импортировать классы java.time изПакет org.threeten.bp (не пакет java.time).

Если вы хотите использовать API ThreeTen Backport, просто включите его зависимость в ваш проект.

0 голосов
/ 27 января 2019

Вы можете использовать SimpleDateFormat для получения ввода.Я использую предопределенный ввод, так как вы хотели вычислить разницу между двумя заданными временами.Вот код для вас.Пожалуйста, обратите внимание, что я выдал ответ как для формата 24, так и для 12 часов.

Получение значения времени сна и пробуждения

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
Date sleepingTime = simpleDateFormat.parse("22:00");
Date wakeUptime = simpleDateFormat.parse("07:00");

Если разница меньше нуля, это происходит в формате 12 часов

long difference = sleepingTime.getTime() - wakeUpTime.getTime(); 
if(difference<0) {
  Date dateMax = simpleDateFormat.parse("24:00");
  Date dateMin = simpleDateFormat.parse("00:00");
  difference=(dateMax.getTime() -sleepingTime.getTime() )+(wakeUpTime.getTime()- 
  dateMin.getTime());
}

Расчет разницы

//days and minutes are optional
int days = (int) (difference / (1000*60*60*24));  
int hours = (int) ((difference - (1000*60*60*24*days)) / (1000*60*60)); 
int min = (int) (difference - (1000*60*60*24*days) - (1000*60*60*hours)) / 
(1000*60);
Log.e("log_tag",hours+" hours"); 

Надеюсь, он ответит на ваш запрос.Спасибо:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...