我有一个对象列表,希望按周数映射它们。
我看过像
这样的东西private static int getWeekOfYear(LocalDate date) {
WeekFields wf = WeekFields.of(Locale.getDefault());
return date.get(wf.weekOfYear());
}
问题在于我不希望用一年中的周数来做到这一点。
我希望Map<Integer, List<DTO>>
Integers
为1,2,3,......
我按日期对原始List<DTO>
进行了排序,然后我可以获得第一个DTO.getDate()
以确定第1周何时开始。
我的问题是迭代DTO's
并确定每个星期的编号。我觉得我必须找到一周中的某一天,然后计算出开始的天数下个星期,例如如果第一个日期是星期三,那么第2周将在5天内开始,然后每个后续星期将再延长7天。
我真的很难找到一种很好的写作方式。所以我想知道是否有人能想出一个创建这个Map
的好方法吗?
由于
答案 0 :(得分:3)
基本上,您希望在日期进行此类计算时查看新的Java8 date/time API。
然后请注意:您确定要在此处使用地图吗? 如果我输入正确,你说密钥将运行1,2,3,...无论如何?那么 - 当你知道键只是一个数字序列时,为什么不使用列表?
另一种替代方法是使用TreeSet和自定义隔离专区。如果您使用比较器根据日期排序您的DTO对象,TreeSet将自动将它们按正确顺序排列!
答案 1 :(得分:1)
尝试JodaTime的一周中的格式:http://joda-time.sourceforge.net/field.html#weekyear
基于星期的年份是将日期表示为星期几的日期, 周数和年(基于周)。以下描述是 此方法的实现所使用的ISO8601标准 图书馆。基于一周的一周,周数从1到52-53。第一天 本周定义为星期一,给出值1.第一周 一年的定义是至少有四天的第一周 那一年。由于这个定义,第1周可能延伸到 去年,第52/53周可能延续到下一年。 因此需要一年的农田年。例如,2003-01-01 是星期三。这意味着五天,周三到周日, 那个星期是在2003年。因此整个星期被认为是 2003年的第一周。因为所有周都是星期一开始,所以是第一周 2003年开始于2002-12-30,即。在2002年。基于周的一年有一个 特定的文本格式。
2002-12-30 (Monday 30th December 2002) would be represented as 2003-W01-1
2003-01-01 (Wednesday 1st January 2003) would be represented as 2003-W01-3.
答案 2 :(得分:1)
WeekField
有一个重载方法,用于指定一周的开始日期和第一周的天数。
由于DTO List
已经排序,一周的第一天将是开始日,而那一天的7天将是下一周。
List<DTO> dtos = ...// sorted
LocalDate firstDate = dtos.get(0).getDate();
WeekFields weekFields = WeekFields.of(firstDate.getDayOfWeek(), 7); // to override the default start day and no of days in first week
Map<Integer, List<DTO>> map = dtos.stream().collect(Collectors.groupingBy(dto -> dto.getDate().get(weekFields.weekOfYear())));
答案 3 :(得分:1)
您需要做的是找到第一个日期的一周的第一天,并使用此日期创建地图作为参考:
private static Map<Long, List<DTO>> mapByWeek(final List<DTO> dtos) {
if (dtos.isEmpty())
return Collections.emptyMap();
// find the first day of first week
final LocalDate referenceDate = dtos.stream().sorted(Comparator.comparing(DTO::getDate)).findFirst()
.map(dto -> dto.getDate().with(WeekFields.of(Locale.getDefault()).dayOfWeek(), 1)).get();
// group by number of weeks of difference with the reference date
return dtos.stream().collect(Collectors.groupingBy(dto -> ChronoUnit.WEEKS.between(referenceDate, dto.getDate()) + 1));
}