查询某年某月一个月的数据,以日历的形式展示

市场上有些这样的应用,会展示某年某月一个月的数据,比如女神们经常用的“大姨妈”APP,一些游戏的用户签到信息,等等

img

那我们在写后台接口的时候,就需要返回这一个月的数据,今天我就分享一下笔者经常在工作中使用的方法。

数据库DB中存了许多用户的应用数据,每条数据有一个日期字段,可以是Integer类型(yyyyMMdd),可以是String类型(yyyy-MM-dd),还可以是Date类型.

首先定义了一个这样的类来保存某天的数据:

1
2
3
4
5
6
7
8
9
public class CalendarDate<T>{
public Integer day;

public Integer weekDay;

public Boolean isToday;

public T info;
}

四个字段的意思分别是:day-这个月的第几天,weekDay-星期几,isToday-是否是今天,info-该天的用户数据。

请求接口如下,请求需要年和月两个参数:

1
2
3
4
5
6
7
8
9
@GetMapping("/calendar")
public List<CalendarDate<List<String>>> calendarDates(@RequestParam Integer year, @RequestParam Integer month) {
Function<String, Optional<List<String>>> function = day -> {
List<String> datas = new ArrayList<>();
datas.add(day); // DB: datas = tableMapper.findByDay(day);
return Optional.of(datas);
};
return DateUtils.calendar(year, month, function);
}

重点就是下面封装好的工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class DateUtils {


public static <T> List<CalendarDate<T>> calendar(int year, int month, Function<String, Optional<T>> function) {
List<CalendarDate<T>> cdList = new ArrayList<>();
int monthDays = monthDays(year, month);
CalendarDate<T> cdR;
for (int day = 1; day <= monthDays; day++) {
cdR = new CalendarDate<>();
cdR.day = day;
LocalDate date = LocalDate.of(year, month, day);
cdR.weekDay = dayOfWeek(date);
cdR.isToday = isToday(date);
if (function != null) {
Optional<T> optional = function.apply(date.toString());
if (optional.isPresent()) {
cdR.info = optional.get();
}
}
cdList.add(cdR);
}
return cdList;
}

private static boolean isToday(LocalDate date) {
LocalDate today = LocalDate.now();
return date.getYear() == today.getYear() &&
date.getMonth() == today.getMonth() &&
date.getDayOfMonth() == today.getDayOfMonth();
}

private static int dayOfWeek(LocalDate date) {
return null == date ? 0 : date.getDayOfWeek().getValue();
}

private static int monthDays(int year, int month) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DATE, 1);
calendar.roll(Calendar.DATE, -1);
return calendar.get(Calendar.DATE);
}
}

针对不同的业务要求,编写不一样的function函数,就可以返回日历形式的用户数据了。

项目地址如下:https://github.com/cnblogs-projects/cnblogs-calendar