Разница во времени Java выводит отрицательное значение и неправильные значения - PullRequest
0 голосов
/ 05 октября 2018

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

    Date d3 = null;
    Date d4 = null;
    List<String> activeTimeList = new ArrayList();
    int c = Integer.parseInt(cycle.get("Cycle No:").toString());
    try {
        for(int i = 0; i<c;i++) {
            SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy HH:mm", Locale.US); //("MM/dd/yyyy HH:mm:ss");
            format.setTimeZone(TimeZone.getTimeZone("GMT"));
            String cycleEndTm = cycle.get("End Time"+i+"").toString().trim();
            String cycleStartTm = cycle.get("Start Time"+i+"").toString().trim();

            d3 = format.parse(cycleEndTm);
            d4 = format.parse(cycleStartTm);
            long diff =  d3.getTime() - d4.getTime();
            long diffSeconds = diff / 1000 % 60;
            long diffMinutes = diff / (60 * 1000) % 60;
            long diffHours = diff / (60 * 60 * 1000) % 24;
            long diffDays = diff / (24 * 60 * 60 * 1000);
            String time1 = diffDays+"."+diffHours+"."+diffMinutes+"."+diffSeconds;

Log :
0.-10.-7.0

d4 = 02-11-2017 16: 47
d3 = 02-11-2017 17: 27 Разница = 0.-10.-7.0 Не можете получить правильную разницу во времени?Что мне здесь не хватает?Примечание **: cycleEndTm -cycleStarttime должен давать положительный результат.Я читаю циклEndTime и время начала с карты.Это требование.

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

java.time

Этот ответ не решает проблему, о которой вы спрашивали.В любом случае, я рекомендую использовать java.time, современный API даты и времени Java.Первая версия здесь требует как минимум Java 9 .Далее следуют Java 6, 7 и 8.

    Map<String, Object> cycle = Map.of("Cycle No:", 1, 
            "Start Time0", "02-11-2017 16:47",
            "End Time0", "02-11-2017 17:27");

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm", Locale.US);
    List<String> activeTimeList = new ArrayList<>();
    int c = Integer.parseInt(cycle.get("Cycle No:").toString());
    try {
        for(int i = 0; i < c; i++) {
            String cycleEndTm = cycle.get("End Time" + i).toString().trim();
            String cycleStartTm = cycle.get("Start Time" + i).toString().trim();

            LocalDateTime d4 = LocalDateTime.parse(cycleStartTm, formatter);
            LocalDateTime d3 = LocalDateTime.parse(cycleEndTm, formatter);

            Duration diff = Duration.between(d4, d3);
            String time1 = String.format(Locale.US, "%d.%d.%d.%d", 
                    diff.toDays(), diff.toHoursPart(), 
                    diff.toMinutesPart(), diff.toSecondsPart());

            activeTimeList.add(time1);
        }
        System.out.println(activeTimeList);
    } catch (DateTimeParseException dtpe) {
        System.err.println(dtpe);
    }

Это печатает:

[0.0.40.0]

Методы toXxxPartкласса Duration, который я использую для форматирования, нет в Java 8 .Поэтому, если вы используете Java 8, вместо этого можно выполнить форматирование следующим образом:

            long days = diff.toDays();
            diff = diff.minusDays(days);
            long hours = diff.toHours();
            diff = diff.minusHours(hours);
            long minutes = diff.toMinutes();
            diff = diff.minusMinutes(minutes);
            long seconds = diff.getSeconds();
            String time1 = String.format(Locale.US, "%d.%d.%d.%d", 
                    days, hours, minutes, seconds);

Вывод будет таким же, как и раньше.

Если кто-то читает, использует Java6 или 7 , получите библиотеку ThreeTen Backport , и код Java 8 также должен работать там.

Что пошло не так в вашем коде?

ЕдинственноеПроблема в размещенном вами коде заключается в том, что вы используете устаревшие и плохо разработанные классы даты и времени, Date, SimpleDateFormat и TimeZone.В вашем коде нет ничего, объясняющего, как вы ошиблись, отрицательные значения, поэтому я подозреваю, что вы не анализировали строки, которые, как вы думали, вы анализировали.

0 голосов
/ 05 октября 2018

tl; dr

Используйте современные java.time классы, никогда Date.Преобразуйте любые Date в java.time.Instant.

Duration                              // Represent a span-of-time as 24-hour days, hours, minutes, seconds, and nanoseconds.
.between(                             // Calculate elapsed time.
    javaUtilDateStart.toInstant() ,   // Convert any `java.util.Date` to `java.time.Instant`. Never use `Date`; it is a terrible class, ditto for `Calendar`. 
    javaUtilDateStop.toInstant()
)                                      // Returns a `Duration` object.
.toString()                            // Generate text in standard ISO 8601 format.

Или вызовите методы to…Part, чтобы извлечь количество дней, часов и т. Д.

java.time

Вы используете ужасные старые классы даты и времени (Date, Calendar, SimpleDateFormat), которые были вытеснены несколько лет назад классами java.time .

Instant

Очевидно, вам вручают java.util.Date объект.Если возможно, перепишите этот код, чтобы использовать его замену, объект java.time.Instant.Оба представляют момент в UTC, но Instant имеет лучшее разрешение наносекунд, нежели миллисекунд.Если это невозможно, немедленно конвертируйте Date в Instant.Вызовите новые методы преобразования, добавленные к старым классам.

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy class to modern class. Same moment in UTC, same point on the timeline.

Создание текста, представляющего этот момент в стандартном формате ISO 8601 .

Захват текущего момента в формате UTC.

Instant now = Instant.now() ;  // Capture the current moment in UTC.

Duration

Рассчитать прошедшее время как объект Duration.Опять же, это имеет разрешение наносекунд.

Duration d = Duration.between( instant , now ) ;

Создание текста, представляющего прошедшее время, в стандартном формате ISO 8601 .

String output = d.toString() ; 

Или создайте строку,определяя «дни» как 24-часовой отрезок времени без учета календаря.

long days = d.toDaysPart() ;
int hours = d.toHoursPart() ;
int minutes = d.toMinutesPart() ;
int seconds = d.toSecondsPart() ;

String output = days + "." + hours + "." + minutes + "." + seconds ;

Синтаксический анализ строк

Ваш вопрос не ясен относительно ваших входных данных.Если начать со строк, проанализируйте.Во-первых, если возможно, измените источник этих строк, чтобы использовать мудро определенные стандартные форматы ISO 8601 .Если это невозможно, определите шаблон форматирования в соответствии с вводом.

String inputStart = "02-10-2018 10.30";

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu HH.mm" );

Анализируйте ввод как LocalDateTime, так как в нем отсутствует какой-либо индикатор часового пояса или смещения отUTC.

LocalDateTime ldtStart = LocalDateTime.parse( inputStart , f ) ;

A LocalDateTime - это не момент, не представляет точку на временной шкале.Этот класс представляет потенциальных моментов в диапазоне около 26-27 часов, диапазоне часовых поясов по всему земному шару.

Назначьте зону или смещение, предназначенные источником этой строки, длядать контекст, необходимый для определения момента.

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

// Transform the indefinite `LocalDateTime` to a definite moment by assigning the time zone intended by that input string.
ZoneId z = ZoneId.of( "Africa/Tunis" );
ZonedDateTime zdtStart = ldtStart.atZone( z );

Рассчитайте ваш промежуток времени.

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

О 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 и JavaSE 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 .

...