Czy dobrze pobierasz numer tygodnia? Zapewne odpowiesz tak, ale czy zawsze?
Pakiet java.time
zdążył się już dawno zadomowić w naszych projektach i nie ma się co temu dziwić, ponieważ jest to od dawna wyczekiwany następca paskudnego Calendar
’a. Na co dzień pewnie każdy z was korzysta z tworzenia dat lub porównywania ich ze sobą. Działa to świetnie oraz jest niesamowicie proste.
Czasami jednak przychodzi moment, że potrzebujemy nieco więcej informacji niż rok, miesiąc, dzień i godzina. Przykładowo tak jak w tytule naszym zadaniem jest pobrać numer aktualnego tygodnia. Wydawałoby się prosta rzecz, w końcu dość często z tego korzystamy w życiu prywatnym. Jednak tutaj następuje delikatne zaskoczenie, bo w klasie LocalDate
, ani LocalDateTime
, z których zapewne najczęściej korzystacie nie ma metody getCurrentWeek
.
W takich chwilach nie pozostaje nic innego niż sięgnąć do dokumentacji lub szukać rozwiązania w internecie.
WeekFields – w poszukiwaniu numeru tygodnia
Z pomocą przychodzi klasa WeekFields
, która udostępnia kilka przydatnych metod związanych z tygodniami. W zależności od naszych potrzeb, możemy skorzystać z definicji ISO-8601, danego Locale
lub własnych ustawień obsługi dni tygodnia.
WeekFields localeWeekFields = WeekFields.of(Locale.ENGLISH); WeekFields customWeekFields = WeekFields.of(DayOfWeek.TUESDAY, 6); WeekFields isoWeekFields = WeekFields.ISO; isoWeekFields.dayOfWeek(); isoWeekFields.dayOfWeek(); isoWeekFields.weekOfYear(); isoWeekFields.weekOfMonth(); isoWeekFields.weekBasedYear(); isoWeekFields.weekOfWeekBasedYear();
No i tutaj może nas najść delikatna konsternacja, ponieważ są dwie metody, które można wykorzystać przy pobieraniu numeru tygodnia: weekOfYear
i weekOfWeekBasedYear
. Dodatkowo mamy też metodę do pobierania roku (weekBasedYear
), ale przecież rok możemy łatwo sobie pobrać korzystając z metody getYear
w klasie LocalDate
. Sprawdźmy jakie wyniki zwrócą te metody dla dzisiejszej daty.
LocalDate localDate = LocalDate.of(2020, 11, 1); int weekOfYear = localDate.get(weekFields.weekOfYear()); // 44 int weekOfWeekBasedYear = localDate.get(weekFields.weekOfWeekBasedYear()); // 44 int weekBaseYear = localDate.get(weekFields.weekBasedYear()); // 2020 int year = localDate.getYear(); // 2020
Na pierwszy rzut oka wszystko wygląda identycznie, ale gdzieś musi tkwić haczyk. Sprawdźmy wyniki dla innej daty.
LocalDate localDate = LocalDate.of(2021, 1, 1); int weekOfYear = localDate.get(weekFields.weekOfYear()); // 0 int weekOfWeekBasedYear = localDate.get(weekFields.weekOfWeekBasedYear()); // 53 int weekBaseYear = localDate.get(weekFields.weekBasedYear()); // 2020 int year = localDate.getYear(); // 2021
No i tutaj jest dość duże zaskoczenie, ponieważ okazuje się, że pierwszy stycznia 2021 roku może być zarówno zerowym tygodniem jak i pięćdziesiątym trzecim. A jeszcze dziwniejsza rzecz to ta, że używając metody weekBasedYear
jest on w 2020 roku!
O co tutaj chodzi?
W użytym przeze mnie przykładzie skorzystałem z definicji ISO dla WeekFields
. W tym wypadku tydzień zaczyna się od poniedziałku i powinien mieć co najmniej 4 dni. Biorąc to pod uwagę, pierwsze trzy dni stycznia 2021 roku nie wpisują się do tej reguły. W takim układzie te dni przypisane są do 53 tygodnia roku 2020. Analogicznie jest w przypadku pobierania roku. Metoda nazywa się weekBasedYear
, co oznacza, że rok jest podzielony na tygodnie zgodnie z wybraną definicją. Z uwagi, że pierwszy stycznia 2021 roku należy do 53 tygodnia poprzedniego roku, ten właśnie rok jest zwrócony przy korzystaniu z metody weekBasedYear
.
Warto zapamiętać, że numery tygodnia odpowiadają kolejnym czwartkom w roku. Pierwszy czwartek 2021 wypada piątego stycznia, więc jest on w pierwszym tygodniu roku.
W przypadku pobrania numeru tygodnia metodą weekOfYear
dostajemy jeszcze jedną istotną informację. W przypadku kiedy pierwszy tydzień nie spełnia reguł zdefiniowanych w WeekFields
jako numer dostaniemy zero. Analogicznie przy spełnieniu tych definicji tydzień będzie numerowany od jedynki.
Podsumowując, w zależności jaki rezultat chcemy uzyskać powinniśmy po pierwsze zastanowić się z jakiej definicji tygodnia chcemy skorzystać (od którego dnia ma się on zaczynać i ile minimalnie dni musi zawierać) a po drugie wybrać odpowiednią z dostępnych metod.
Dodaj komentarz