为什么要基于一个Integer类型做用户月登录记录
其实Integer类型的范围是2^31 ~2^31 - 1
即我们只要将他看成2进制位,他就有31位,刚好可以记录一个月用户登录的情况
例如 0101
则该用户在这个月的1号和3号登录了,用 0 和 1来记录用户登录的情况
这种方案同样适用于标签系统的设计
package login;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.LinkedHashMap;
import java.util.Map;
public class monthLoginUtil {
/**
* @param bitmap 记录表
* @param startDay 记录表的开始日期
* @param searchDay 要搜索的日期
* @return
*/
public static boolean isMonthLogin(Integer bitmap, LocalDate startDay, LocalDate searchDay) {
long days = ChronoUnit.DAYS.between(startDay, searchDay);//获取时间差
long day = 1L << days;
return (bitmap & day) != 0;
}
/**
* 默认为当前月登录
*
* @param bitmap
* @param searchDay
* @return
*/
public static boolean CurrentMonthLogin(Integer bitmap, LocalDate searchDay) {
LocalDate now = LocalDate.now();
LocalDate localDate = now.withDayOfMonth(1);
return isMonthLogin(bitmap, localDate, searchDay);
}
/**
* 判断一个月内的登录记录
*
* @param bitmap
* @return
*/
public static Map<Integer, Boolean> MonthlyLogins(Integer bitmap) {
int day = 1;
Map<Integer, Boolean> result = new LinkedHashMap<>();
for (int i = 1; i < 32; i++) {
if ((bitmap & day) != 0) {
result.put(i, true);
} else {
result.put(i, false);
}
day = day << 1;
}
return result;
}
/**
* 当日进行了登录
*
* @param bitmap 记录表
* @return
*/
public static Integer currentDayLogin(Integer bitmap) {
LocalDate now = LocalDate.now();
LocalDate localDate = now.withDayOfMonth(1);
return dayLogin(bitmap, localDate, now);
}
/**
* 指定日期进行了登录
*
* @param bitmap 记录表
* @param startDay 开始时间
* @param LoginDate 登录时间
* @return
*/
public static Integer dayLogin(Integer bitmap, LocalDate startDay, LocalDate LoginDate) {
int days = (int) ChronoUnit.DAYS.between(startDay, LoginDate);//获取时间差
int day = 1 << days;
return bitmap ^ day;
}
}
package login;
import java.util.Map;
public class Client {
public static void main(String[] args) {
Integer integer = monthLoginUtil.currentDayLogin(0);
Map<Integer, Boolean> map = monthLoginUtil.MonthlyLogins(integer);
map.forEach((k, v) -> {
System.out.println(k + "===>" + v);
});
}
}