Т.Л., д-р
Используйте поточно-java.time классы вместо резьбовых небезопасным наследство SimpleDateFormat
класса.
DateTimeFormatter f = DateTimeFormatter.ofPattern("MM-dd-uuuu") ;
ZoneId z = ZoneId.of("America/Montreal") ;
…
LocalDate.parse("01-12-2017" , f)
.isBefore(LocalDate.now(z))
Устаревшие классы даты и времени не поточно-
Я заметил, что вы используете singleton для форматере, один статический экземпляр SimpleDateFormat
. Это legacyкласс неthread-safe, как описано в классе JavaDoc:
Синхронизация
Дата форматы не синхронизированы. Рекомендуется создавать отдельные экземпляры формата для каждого потока. Если несколько потоков обращаются к формату одновременно, его необходимо синхронизировать извне.
Ваш отчет о случайной ошибке, по всей видимости, не имеет веской причины, подсказывает мне, что вы используете этот объект из более одного потока за раз. Статический метод с именем process
, и ваше упоминание в комментариях сервера делает меня еще более подозрительным. Время от времени во время выполнения вы сталкиваетесь с столкновением потоков.
Избегайте устаревших классов времени.
Вы используете неприятные старые классы времени, которые теперь legacy, вытесненные классами java.time. Большая часть функциональных возможностей java.time обратно переносится на Java 6 & 7 в ThreeTen-Backport.
Классы java.time используют immutable objects и предназначены для обеспечения потокобезопасности. Так говорит package documentation.
LocalDate
Вы используете объекты даты и времени для даты только значения. Классы java.time включают способ представления даты только. Класс LocalDate
представляет собой значение даты только без времени и без часового пояса.
Часовой пояс имеет решающее значение для определения даты.В любой данный момент дата изменяется по всему миру по зонам. Например, через несколько минут после полуночи в Paris France - это новый день, пока еще «вчера» в Montréal Québec.
Указать proper time zone name в формате continent/region
, такие как America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте аббревиатуру 3-4 буквы, такую как EST
или IST
, так как они не настоящие часовые пояса, не стандартизированные, и даже не уникальные (!).
Класс ZoneId
является потокобезопасным. Таким образом, вы можете сохранить экземпляр для повторного использования в потоках.
ZoneId z = ZoneId.of("America/Montreal");
LocalDate today = LocalDate.now(z);
При представлении даты как строки, я предлагаю использовать стандартные ISO 8601 форматы. Только для даты только ГГГГ-ММ-ДД, например 2017-01-23
. Классы java.time используют эти стандартные форматы по умолчанию при разборе/генерации строк.
LocalDate target = LocalDate.parse("2017-01-23");
Если формат находится вне вашего контроля, используйте DateTimeFormatter
, как показано во многих других вопросах & ответы на переполнение стека. Этот класс является потокобезопасным, поэтому вы можете сохранить экземпляр для повторного использования в потоках.
DateTimeFormatter f = DateTimeFormatter.ofPattern("MM-dd-uuuu");
LocalDate target = LocalDate.parse("01-12-2017" , f);
Сравнение с такими методами, как isEqual
, isBefore
и isAfter
.
if(target.isBefore(today)){
System.out.println("Send a notification indicating the end day has been reached, so the message is not processed.");
} else {
System.out.println("Process the message and applies some business rules");
}
О java.time
java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытесняют неприятные старые legacy классы времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Проект Joda-Time, в настоящее время в maintenance mode, советует перейти на классы java.time.
Чтобы узнать больше, см. Oracle Tutorial. И поиск Stack Overflow для многих примеров и объяснений. Спецификация: JSR 310.
Где получить классы java.time?
- Java SE 8 и SE 9, а затем
- Встроенный.
- Часть стандартного Java API с объединенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и SE 7
- Большая часть Явы.временная функциональность обратно перенесена на Java 6 & 7 в ThreeTen-Backport.
- Android
Если вы можете использовать Java 8 'java.time. *' Я настоятельно рекомендую. – Simon
Спасибо, Саймон, я поддерживаю платформу Java 1.6. – mlavarreda
Тогда, возможно, время в Joda - это вариант – Simon