Java проверяет, что дата на текущей неделе - PullRequest
0 голосов
/ 31 мая 2018

У меня есть дата в виде строки "30.05.2008", и я хочу определить, что это на текущей неделе. Я конвертирую ее в формат даты, используя этот метод:

    public Date convertStringToDate(String dateString) {
    SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
    Date dateInString = null;

    try {

        Date date = formatter.parse(dateString);
        dateInString = date;
        System.out.println(date);
        System.out.println(formatter.format(date));

    } catch (ParseException e) {
        e.printStackTrace();
    }
    return dateInString;
}

И чтобы проверить, если это в течение той же недели, я использую этот метод:

    public boolean isDateInCurrentWeek(Date date) {

    Calendar currentCalendar = Calendar.getInstance();
    int week = currentCalendar.get(Calendar.WEEK_OF_YEAR);
    int year = currentCalendar.get(Calendar.YEAR);
    Calendar targetCalendar = Calendar.getInstance();
    targetCalendar.setTime(date);
    int targetWeek = targetCalendar.get(Calendar.WEEK_OF_YEAR);
    int targetYear = targetCalendar.get(Calendar.YEAR);

    boolean belongs = (week == targetWeek && year == targetYear);

    return belongs;
}

И я использую оба метода следующим образом:

 if(CustomDateClass.isDateInCurrentWeek(convertStringToDate(trans.getTransactionDate()))){
// perform some task
}

Проверка всегда дает сбой и производитложное на каждой дате, даже сегодняшней.Я посмотрел на другие методы, предложенные в других вопросах, и результаты те же.Что я мог пропустить, так это то, что метод не дает правильного результата.

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

tl; dr

org.threeten.extra.YearWeek.from(                     // Represent a standard ISO 8601 week, starting on a Monday, where week # 1 contains first Thursday of the calendar year.
    java.time.LocalDate.parse(                        // Parse an input string into a `LocalDate` object, representing a date-only value without time-of-day and without time zone.
        "05/30/2018" ,
        DateTimeFormatter.ofPattern( "MM/dd/uuuu" )   // Define a formatting pattern to match the input string. The Question’s code failed to do so correctly.
    )
)                                                     // Returns a `YearWeek` object.
.equals(
    YearWeek.now(                                     // Get the current standard ISO 8601 week.
        ZoneId.of( "Atlantic/Canary" )                // Get the week for today’s date as seen in the wall-clock time in use by the people of a certain region (a time zone). 
    )                                                 // Returns a `YearWeek` object.
)

Подробности

Ответ от Arvind правильный, так как ваши шаблоны форматирования не соответствуют вашей входной строке.Но у вас есть и другие проблемы.

java.time

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

LocalDate синтаксический анализ

Анализировать входную строку как LocalDate.Кстати, когда это возможно, используйте стандартный формат ISO 8601 при обмене значениями даты и времени в виде текста.

String input = "05/30/2018" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;

ld.toString (): 2018-05-30

Определение недели

Вы должны определить, что вы подразумеваете под "неделей".Ваше использование проблемного Calendar класса приводит к неделе, определенной культурными нормами нынешнего JVM Locale.

Я подозреваю, что вы, возможно, захотите быть более точным в своем определении недели, поэтомучто ваши результаты не меняются во время выполнения.

Например, мы могли бы использовать стандартное ISO 8601 определение недели .Стандартная неделя начинается в понедельник, а неделя № 1 имеет первый четверг календарного года.Год длится 52 или 53 недели.Последние / первые несколько дней календарного года могут попасть в следующий / предыдущий недельный год.

Мы можем получить доступ к основанному на неделе году и номеру недели LocalDate, используя IsoFields enum.

int weekOfWeekBasedYear = ld.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int weekBasedYear = ld.get ( IsoFields.WEEK_BASED_YEAR );

Давайте создадим строку этих значений в стандартном формате ISO 8601.Стандарт требует, чтобы мы добавляли любой однозначный номер недели с начальным нулем .

String weekIso = 
    weekBasedYear + 
    "-W" + 
    String.format("%02d", weekOfWeekBasedYear) 
;

2018-W22

Текущая неделя

Вы хотите сравнить неделю введенной даты с текущей неделей.Чтобы получить текущую неделю, нам нужна текущая дата.

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

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

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

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

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

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

int todayWeekOfWeekBasedYear = ld.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int todayWeekBasedYear = ld.get ( IsoFields.WEEK_BASED_YEAR );

Создайте строку, как мы это сделаливыше.

String todayWeekIso = todayWeekBasedYear + "-W" + String.format("%02d", todayWeekOfWeekBasedYear) ;

Сравнить.

boolean isDateInCurrentWeek = weekIso.equalsIgnoreCase​( todayWeekIso ) ;

Ярлык: DateTimeFormatter.ISO_WEEK_DATE

Вместо того, чтобы извлекать номера недели и года для построения строки, мы можем позволитьDateTimeFormatter делай ту же самую работу.Константа DateTimeFormatter.ISO_WEEK_DATE генерирует строку в стандартном формате недели ISO 8601, включая номер дня недели (1-7 для понедельника-воскресенья).

String inputWeekDate = ld.format( DateTimeFormatter.ISO_WEEK_DATE ) ;

2018-W22-3

Сделайте то же самое для текущей недели.

String currentWeekDate = today.format( DateTimeFormatter.ISO_WEEK_DATE ) ;

2018-W22-3

Обрезать последние два символа, дефис и номер дня недели.

String inputWeek = inputWeekDate.substring( 0 , 8 ) ;
String currentWeek = currentWeekDate.substring( 0 , 8 ) ;

Сравнить.

boolean isDateInCurrentWeek = inputWeek.equalsIgnoreCase​( currentWeek ) ;

ThreeTen-Extra library

Эта работа с неделями станет проще, если мы добавим библиотеку ThreeTen-Extra в наш проект.Тогда мы можем использовать его YearWeek класс.

YearWeek yearWeekThen = YearWeek.from( ld ) ;
YearWeek yearWeekNow = YearWeek.now( ZoneId.of( "Europe/Berlin" ) ) ;

boolean isDateInCurrentWeek = yearWeekThen.equals( yearWeekNow ) ;

О 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 API с встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 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 .

0 голосов
/ 31 мая 2018

Проблема в том, что формат даты 05/30/2018 не соответствует dd/MM/yyyy.

Вместо этого используйте MM/dd/yyyy.

...