Как проверить, прошла ли определенная дата

У меня есть строка формы "mm/yyyy", и я хочу сравнить ее с датой локальной системы.

Я подумал о том, чтобы использовать таблицу преобразования между моим месяцем и полем MONTH в календаре, например:

    Calendar cal = Calendar.getInstance();
    String date = "07/2014";
    String month = date.subString(0, 2);
    int monthToCompare;
    if (month.equals("01"))
      monthToCompare = cal.JANUARY;
    if (month.equals("02"))
      monthToCompare = cal.FEBRUARY;
    ...

И затем сравнивая вручную с if. Мне это не нравится, потому что я считаю слишком длинным для такой простой операции.

Другим вариантом, о котором я думал, является получение текущего Date() и использование метода before(). Это означало бы перевод моей даты в формат даты, но простые способы сделать это устарели, я должен указать количество миллисекунд, и я не знаю, как легко это сделать (учитывая високосные годы, исправления календаря и т.д. с 1970 г.).

Ответ 1

Используя ответ @Mifmif, я, наконец, решил проблему с помощью

    if (new SimpleDateFormat("MM/yyyy").parse(date).before(new Date())) {
      ...
    }

Ответ 2

Попробуйте следующее:

new SimpleDateFormat("MM/yyyy").parse("07/2014").compareTo(new Date());

Ответ 3

TL;DR

YearMonth.parse( 
    "07/2014" , 
    DateTimeFormatter.ofPattern( "MM/uuuu" )
).isAfter(
    YearMonth.now(
        ZoneId.of( "Africa/Tunis" )
    )
)

java.time

В современном решении используются классы java.time, а не неприятные старые классы времени.

Только год и месяц

Чтобы представить целый месяц, используйте класс YearMonth.

String input = "07/2014" ; 
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/uuuu" ) ;
YearMonth ym = YearMonth.parse( input , f ) ;

Советы. Используйте такие YearMonth объекты на всей вашей кодовой базе, а не просто строку. И когда вам нужна строка для обмена данными, используйте стандартный ISO 8601 формат: YYYY-MM. Классы java.time используют стандартные форматы по умолчанию при разборе/генерации строк, поэтому нет необходимости определять шаблон форматирования.

Текущий год-месяц

Определение текущего года-месяца означает определение текущей даты.

Часовой пояс имеет решающее значение для определения даты. В любой данный момент дата изменяется по всему миру по зонам. Например, через несколько минут после полуночи в Париж Франция - это новый день, пока еще "вчера" в Монреаль Квебек.

Если часовой пояс не указан, JVM неявно применяет текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент, поэтому ваши результаты могут отличаться. Лучше указывать желаемый/ожидаемый часовой пояс явно как аргумент.

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

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Если вы хотите использовать текущий часовой пояс JVMs, запросите его и передайте в качестве аргумента. Если этот параметр опущен, то действующий по умолчанию JVM применяется неявно. Лучше быть явным, поскольку значение по умолчанию может быть изменено в любой момент во время выполнения любым кодом в любом потоке любого приложения в JVM.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Такая же идея применяется для получения текущего YearMonth: передать a ZoneId.

YearMonth currentYearMonth = YearMonth.now( z ) ;

Сравнить

Сравните с помощью методов isBefore, isAfter и equals.

boolean isAfterCurrentYearMonth = ym.isAfter( currentYearMonth ) ;

О java.time

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

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

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

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

  • Java SE 8, Java SE 9, а затем
    • Встроенный.
    • Часть стандартного Java API с объединенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональных возможностей java.time портирована на Java 6 и 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии реализаций пакетов Android классов java.time.
    • Для более раннего Android проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP....

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