Из года создать недели в map

Рейтинг: 0Ответов: 1Опубликовано: 10.03.2023

Есть такие даты

[
    {
    "name" : "2022-07-20",
    "percentY" : "64.8 ",
    "main" : 842,
    "y" : 546,
    "z" : 0
  }, 
{
    "name" : "2022-07-25",
    "percentY" : "0.0 ",
    "main" : 1354,
    "y" : 0,
    "z" : 0
  }, {
    "name" : "2022-07-26",
    "percentY" : "0.0 ",
    "main" : 30,
    "y" : 0,
    "z" : 0
  }]

Нужно эти даты сгруппировать по неделям. так начинается с июля то и неделя там 29. Таким образом , чтоб все даты которые входит в 29 неделю выводились так: {29 - 2 } . Значит что, в 29 неделе 2 даты . И так для всех остальных дат

Ответы

▲ 0

Для группировки по номеру недели следует использовать класс WeekFields из Java Date/Time API (см. ответ на похожий вопрос: Как сгруппировать строки по неделям, месяцам и кварталам?).

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

Если дней в первой неделе меньше минимума, то она будет считаться как 52 неделя прошлого года для метода WeekFields::weekOfWeekBasedYear или 0 для WeekFields::weekOfYear.

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

public static Map<Integer, Integer> datesByWeek(Supplier<TemporalField> weekField, List<String> dates) {
    return dates.stream()
        .collect(Collectors.groupingBy(
            d -> LocalDate.parse(d).get(weekField.get()),
            LinkedHashMap::new, // поддержать порядок вставки
            Collectors.summingInt(d -> 1)
    ));
}

Тест для разных экземпляров WeekFields c первым и последним днём года:

var dates = Arrays.asList("2022-01-01", "2022-07-20", "2022-07-25", "2022-07-26", "2022-12-31");        
Supplier<TemporalField> weekFields = WeekFields.of(DayOfWeek.MONDAY, 1)::weekOfWeekBasedYear;
var byWeekMon = datesByWeek(weekFields, dates);

System.out.println("MON: " + byWeekMon);

var byWeekSun = datesByWeek(WeekFields.SUNDAY_START::weekOfYear, dates);
System.out.println("SUN: " + byWeekSun);        

var byWeekIso = datesByWeek(WeekFields.ISO::weekOfYear, dates);
System.out.println("ISO: " + byWeekIso);        

Результаты:

MON: {1=2, 30=1, 31=2}        // номер недели 1 для начала и конца года
SUN: {1=1, 30=1, 31=2, 53=1}
ISO: {0=1, 29=1, 30=2, 52=1}

Кстати, ни по одному календарю не выходит, что 25 и 26 июля 2022 года пришлись на 29 неделю.

введите сюда описание изображения