Путаница сравнения дат
Я имею due_date
знак равно 2014-05-09 11:36:41.816
,
Я хочу проверить условие, что если сегодня дата совпадает с due_date
или же 1 day less then due_date
тогда пользователь может renew
другой мудрый должен показать сообщение, что too early to renew
, значит, если я возобновлю на date 8
тогда пользователь может сделать, но если пользователь делает это на date 7
тогда ему не разрешено и выводить сообщение.
Я знаю, что проверить на тот же день означает date 9
, я могу использовать:
Timestamp t = new Timestamp(new Date().getTime());
if (t.compareTo(due_date)==0){
//renew book
}
но я не знаю, как это сделать за 1 день до расчета. Таким образом, любое руководство, чтобы сделать для этого.
3 ответа
Достойная библиотека времени и даты
Вы должны использовать либо Joda-Time, либо новый java.time в Java 8, так как старые классы java.util.Date и.Calendar общеизвестно проблематичны.
Часовой пояс
Вы не должны игнорировать вопрос о часовом поясе. Пропуск часового пояса означает, что часовой пояс вашего хоста JVM (хост-компьютера) будет применяться по умолчанию. Ваши результаты будут отличаться.
Определение "день" и "вчера" зависит от вашего часового пояса.
Используйте правильное название часового пояса (в основном, континент слеш город). Избегайте 3 или 4 буквенных кодов, поскольку они не являются ни стандартизированными, ни уникальными.
Если во входной строке нет смещения часового пояса, то есть в UTC, укажите с помощью встроенной константы DateTimeZone.UTC
,
интервал
Joda-Time предлагает класс Interval для определения промежутка времени. В вашем случае интервал составляет два дня, день срока платежа плюс день раньше. (Кстати, и ваши опубликованные вопросы, и ваше программирование улучшатся, если вы будете усерднее работать над сосредоточением внимания и упрощением своей проблемы, как я только что сделал в предыдущем предложении.)
Полуоткрытый
Обычно в работе с датой и временем мы используем "полуоткрытый" подход для определения диапазона. Это означает, что начало включительно, а окончание - исключительно для сравнения. Так что для вашей цели мы хотим убежать от first moment of the day before due date
до, но не включая first moment of the day *after* due date
,
ISO 8601
Ваша входная строка почти в стандартном формате ISO 8601. Просто замените ПРОБЕЛ на T
, Joda-Time имеет встроенные парсеры для форматов ISO 8601.
Пример кода
Пример кода в Joda-Time 2.3.
String inputDueDateRaw = "2014-05-09 11:36:41.816"
String inputDueDate = inputDueDateRaw.replace( " ", "T" );
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime due = new DateTime( inputDueDate, timeZone ); // Note the time zone by which to interpret the parsing of the string.
DateTime dayBeforeDue = due.withTimeAtStartOfDay().minusDays( 1 ).withTimeAtStartOfDay();
DateTime dayAfterDue = due.withTimeAtStartOfDay().plusDays( 1 ).withTimeAtStartOfDay(); // Half-open. Up to but not including day after.
Interval renewalInterval = new Interval( dayBeforeDue, dayAfterDue );
Проверьте, находится ли текущий момент в этом интервале, используя полуоткрытый подход к сравнению.
boolean isNowEligibleForRenewal = renewalInterval.contains( DateTime.now() );
Фактическая стоимость a.compareTo(b)
Возвращение не имеет смысла. Единственное, чему вы можете доверять, это если a
"больше" чем b
и если это отрицательно, a
"меньше". Вы не можете рассчитывать на его абсолютное значение, чтобы определить разницу между ними.
Вы можете, однако, просто сравнить представление времени в Unix обеих дат:
TimeStamp due_date = ...;
long dueDateMillis = due_date.getTime();
long t = System.currTimeMillis();
long threshold = 24L * 60L * 60L * 1000L; // One day in milliseconds
if (dueDateMillis - t <= threshold) {
// Renew book
}
Другой способ сделать это - использовать объект Calendar:
Calendar today = Calendar.getInstance();
today.setTimeInMillis(System.currentTimeMillis()); // time today
Timestamp dueDateTs = new Timestamp(...);
Calendar dueDate = Calendar.getInstance();
dueDate.setTimeInMillis(dueDateTs.getTime());
dueDate.roll(Calendar.DAY_OF_YEAR, false); // to subtract 1 day
if(today.after(dueDate)) {
// do your magic
}