Автор оригинала: Jonathan Cook.
1. введение
В этой статье мы рассмотрим несколько вариантов, которые мы можем использовать в Java, чтобы получить номер недели для данной даты. Мы начнем с рассмотрения нескольких вариантов устаревшего кода, использующего классы до Java 8. После этого мы рассмотрим более новый API Date Time в пакете java.time , который был представлен в Java 8.
2. До Java 8
До Java 8 вычисления даты и времени выполнялись в основном с использованием классов Date и Calendar . Обычно мы создаем Календарь , а затем из него можно извлечь необходимую нам информацию, используя различные константы.
2.1. Получить Номер Недели С Помощью Полей Календаря
Давайте рассмотрим наш первый пример:
Calendar calendar = Calendar.getInstance(locale); calendar.set(year, month, day); int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
Мы просто создаем экземпляр Calendar для данного Locale и устанавливаем год, месяц и день, и, наконец, получаем поле WEEK_OF_YEAR из объекта calendar . Это вернет номер недели в текущем году.
Теперь давайте посмотрим, как вызвать этот метод из одного из наших модульных тестов:
@Test public void givenDateUsingFieldsAndLocaleItaly_whenGetWeekNumber_thenWeekIsReturnedCorrectly() { Calendar calendar = Calendar.getInstance(Locale.ITALY); calendar.set(2020, 10, 22); assertEquals(47, calendar.get(Calendar.WEEK_OF_YEAR)); }
Мы должны быть осторожны при принятии этого подхода, так как поле месяца в классе Calendar основано на нуле. Это означает, что если мы хотим указать декабрь, то нам нужно использовать число 11, что часто может привести к путанице.
2.2. Получить Номер Недели С Помощью Настроек Локали
В этом предпоследнем примере мы рассмотрим, какой эффект может иметь применение некоторых дополнительных настроек к нашему Календарю :
Calendar calendar = Calendar.getInstance(); calendar.setFirstDayOfWeek(firstDayOfWeek); calendar.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); calendar.set(year, month, day); int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
Класс Calendar определяет два метода:
- Установить первый день недели
- setMinimalDaysInFirstWeek
Эти методы влияют на то, как мы вычисляем номер недели. Обычно оба эти значения берутся из Локали при создании Календаря . Но также можно установить первый день недели и минимальные дни в первую неделю года вручную.
2.3. Языковые различия
Локаль играет важную роль в том, как рассчитывается номер недели:
@Test public void givenDateUsingFieldsAndLocaleCanada_whenGetWeekNumber_thenWeekIsReturnedCorrectly() { Calendar calendar = Calendar.getInstance(Locale.CANADA); calendar.set(2020, 10, 22); assertEquals(48, calendar.get(Calendar.WEEK_OF_YEAR)); }
В этом модульном тесте мы изменили только языковой стандарт Календаря , чтобы использовать Языковой стандарт.КАНАДА вместо Locale.ИТАЛИЯ и теперь возвращенный номер недели 48 вместо 47 .
Оба результата верны. Как упоминалось ранее, это происходит потому, что каждый Locale имеет разные настройки для setFirstDayOfWeek и setMinimalDaysInFirstWeek методов .
3. Java 8 Date Time API
Java 8 представила новые API для Даты и времени для устранения недостатков старого java.util.Дата и java.util.Календарь .
В этом разделе мы рассмотрим некоторые варианты получения номера недели с даты с помощью этого нового API.
3.1. Получить номер недели, используя числовые значения
Аналогично, как мы видели ранее с Calendar , мы также можем передавать значения года, месяца и дня непосредственно в Локальные данные :
LocalDate date = LocalDate.of(year, month, day); int weekOfYear = date.get(WeekFields.of(locale).weekOfYear());
Преимущество по сравнению с нашими примерами до Java 8 заключается в том, что у нас нет проблемы с тем, что поле месяца основано на нуле.
3.2. Получить Номер Недели С Помощью Хронополя
В этом последнем примере мы увидим, как использовать перечисление ChronoField , которое реализует Temporal Field interface :
LocalDate date = LocalDate.of(year, month, day); int weekOfYear = date.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
Этот пример аналогичен использованию календаря .WEEK_OF_YEAR это константа, которую мы видели ранее, но с использованием хронополя.ALIGNED_WEEK_OF_YEAR .
4. Заключение
В этом кратком руководстве мы проиллюстрировали несколько способов получения номера недели с даты с помощью простой Java.
Как всегда, полный исходный код статьи доступен на GitHub .