Из года создать недели в map
Есть такие даты
[
{
"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 даты . И так для всех остальных дат
Ответы (1 шт):
Для группировки по номеру недели следует использовать класс 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 неделю.
