Разница между двумя строками даты в Java - PullRequest
0 голосов
/ 02 июня 2011

Я пытаюсь вычислить разницу между двумя строками даты, которые взяты у пользователя через html-форму в формате (гггг / мм / дд). Код:

public boolean diffDate() throws ParseException
 {
     date1 = getissuedate();
     date2 = getduedate();
         Calendar cal1 = Calendar.getInstance();
    Calendar cal2 = Calendar.getInstance();
    SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy/MM/dd");
    SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy/MM/dd"); 
Date date_old = formatter1.parse(date1);
Date date_new = formatter2.parse(date2);
long milis1 = date_old.getTime();
long milis2 = date_new.getTime();

long diff = milis2 - milis1;       

    if( diff<3 || diff>3)
    {
        return true;
    }
    else 
    {       
        return false;
    }       
 }

Сейчас я использую условие ifсообщить об ошибке на моей веб-странице, если разница между датами не равна 3. Код:

try {
        if(diffDate())
        {
            errors.add("duedate", new ActionMessage("error.duedate.required"));
        }
    } catch (ParseException ex) {
        Logger.getLogger(IssueBookForm.class.getName()).log(Level.SEVERE, null, ex);
    }

, где error.duedate.required сопоставлен с "датой проверки"

Итак,проблема "проверка даты", ошибка печатается для любого значения обеих строк даты.

Ответы [ 6 ]

2 голосов
/ 02 июня 2011

Вы проверяете, отличаются ли две даты на 3 миллисекунды, что почти всегда будет верно. Если вы действительно хотите 3 дня, значение должно быть 3 * 86400 * 1000. Если вы заботитесь о том, что происходит с изменениями високосных секунд и перехода на летнее время, проблема становится более сложной.

1 голос
/ 02 июня 2011

java.util.Calendar имеет метод add, который принимает количество и единицу времени, и метод с именем compareTo, который принимает другой календарь.Вы должны использовать их.

1 голос
/ 02 июня 2011

вы никогда не получите разницу в 3 миллисекунды между двумя датами, полученными из строки в формате гггг / мм / дд (максимальная точность будет 24 часа)

если вы хотите разницу в 3 дня, используйте 24*60*60*1000 для коэффициента масштабирования значений

1 голос
/ 02 июня 2011

Если вы анализируете даты с разрешением 1 день, т. Е. 86 000 000 миллисекунд, вы никогда не получите ситуацию, когда они будут точно отличаться на 3 мс.

getTime () возвращает время в мс с момента «начала эпохи», поэтому возвращает миллисекунды или 1/1000 с.

diff < 3 || diff > 3

совпадает с

diff != 3

Если вы хотите определить даты, которые различаются ровно на 3 дня, вы можете разделить число миллисекунд на количество мс / день перед сравнением.

1 голос
/ 02 июня 2011

Ваше состояние diff <3 || diff> 3 эквивалентно diff! = 3, а diff выражается в миллисекундах. Это выражение никогда не будет правдой.

0 голосов
/ 09 мая 2017

ТЛ; др

java.lang.Math.abs (
    ChronoUnit.DAYS.between(
        LocalDate.parse( "2017/01/23".replace( "/" , "-" ) ) ,
        LocalDate.parse( "2017/02/14".replace( "/" , "-" ) ) 
    )
) > 3L

Использование java.time

Современный подход использует классы java.time , а не трудоемкие старые классы даты и времени (Date, Calendar и т. Д.).

Ваши входные строки практически соответствуют стандартному формату ISO 8601 для значений только для даты: ГГГГ-ММ-ДД. Для полного соответствия замените символы косой черты на дефис.

String inputA = "2017/01/23".replace( "/" , "-" ) ;
String inputB = "2017/02/14".replace( "/" , "-" ) ;

Классы java.time по умолчанию используют стандартные форматы при разборе / генерации строк. Поэтому не нужно указывать шаблон форматирования.

LocalDate ldA = LocalDate.parse( inputA );
LocalDate ldB = LocalDate.parse( inputB );

Остальная часть вашего Вопроса не имеет смысла, так как тестируется на +/- три миллисекунды, что не может быть правдой между датами. Видимо, вы хотели проверить количество дней. Для этого используйте перечисление ChronoUnit.

long daysBetween = ChronoUnit.DAYS.between( ldA , ldB );

Если вторая дата действительно наступает за до первой даты, результатом является отрицательное число. Похоже, вы хотите проверить в любом случае, используя допуск ± 3. Используйте метод java.lang.Math class ’abs для проверки абсолютного значения нашего результата.

Метод ChronoUnit.DAYS.between возвращает примитив long. Таким образом, наш тест, сравнивающий этот результат с нашим пределом в три, должен соответствовать этому типу. Обратите внимание на использование L, чтобы указать, что 3L является примитивным значением три типа long. Компилятор может обновить значение по умолчанию 3 с int (32-разрядный) до long (64-разрядный), но я предпочитаю быть явным, используя 3L.

if( abs( daysBetween ) > 3L ) { … }

О java.time

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

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

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Где получить классы java.time?

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

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