1. Введение
В этой статье мы рассмотрим несколько вариантов, которые мы можем использовать в Java для получения номера недели для заданной даты. Мы начнем с рассмотрения нескольких вариантов устаревшего кода с использованием классов до Java 8. Затем мы рассмотрим более новый API Date Time в пакете java.time
, представленном в Java 8.
2. До Java 8
До Java 8 вычисления даты и времени выполнялись в основном с использованием классов Date
и Calendar .
Обычно мы создаем Calendar
, а затем можно извлечь из него нужную нам информацию, используя различные константы.
2.1. Получить номер недели с помощью полей календаря
Давайте посмотрим на наш первый пример:
Calendar calendar = Calendar.getInstance(locale);
calendar.set(year, month, day);
int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
Мы просто создаем экземпляр календаря
для данной локали
и устанавливаем год, месяц и день, и, наконец, мы получаем поле WEEK_OF_YEAR
из объекта календаря .
Это вернет номер недели в текущем году.
Теперь давайте посмотрим, как вызвать этот метод из одного из наших модульных тестов:
@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
определяет два метода:
setFirstDayOfWeek
setMinimalDaysInFirstWeek
Эти методы влияют на то, как мы вычисляем номер недели. Обычно оба эти значения берутся из Locale
при создании Calendar
. Но также возможно установить первый день недели и минимальное количество дней первой недели года вручную.
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.CANADA
вместо Locale.ITALY,
и теперь возвращаемый номер недели равен 48
вместо 47
.
Оба результата верны. Как упоминалось ранее, это происходит потому, что каждый Locale
имеет разные настройки для методов setFirstDayOfWeek
и setMinimalDaysInFirstWeek
.
3. API даты и времени
Java 8
В Java 8 представлены новые API для даты
и времени
, чтобы устранить недостатки старых java.util.Date
и java.util.Calendar
.
В этом разделе мы рассмотрим некоторые варианты получения номера недели из даты с помощью этого нового API.
3.1. Получите номер недели, используя числовые значения
Аналогично, как мы видели ранее с Calendar
, мы также можем передавать значения года, месяца и дня непосредственно в LocalDate
:
LocalDate date = LocalDate.of(year, month, day);
int weekOfYear = date.get(WeekFields.of(locale).weekOfYear());
Преимущество по сравнению с нашими примерами до Java 8 заключается в том, что у нас нет проблемы с отсчетом поля месяца от нуля.
3.2. Получить номер недели с помощью Chronofield
В этом последнем примере мы увидим, как использовать перечисление ChronoField
, которое реализует интерфейс TemporalField
:
LocalDate date = LocalDate.of(year, month, day);
int weekOfYear = date.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
Этот пример похож на использование константы Calendar.WEEK_OF_YEAR
int
, которую мы видели ранее, но с использованием ChronoField.ALIGNED_WEEK_OF_YEAR
.
4. Вывод
В этом кратком руководстве мы проиллюстрировали несколько способов получения номера недели из даты с использованием простой Java.
Как всегда, полный исходный код статьи доступен на GitHub .