如何配合Date类型使用UserDao实现Room数据库按时间段查询数据
解决方案
你的TypeConverter会自动把Date对象转成对应的毫秒时间戳,和数据库存储的数值做对比,只要保证传入的
from是查询范围的起始时刻,to是查询范围的结束时刻即可。
推荐优先使用Java 8+的Time API计算时间范围,可避免旧Calendar API的多线程安全、逻辑冗余等问题,低版本安卓可直接开启coreLibraryDesugaring脱糖支持即可使用。
java.time API实现(推荐)
1. 查询当日数据
// 当日0点0分0秒 val startOfDay = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() val fromDate = Date(startOfDay) // 当日23点59分59秒999毫秒 val endOfDay = LocalDate.now().atTime(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() val toDate = Date(endOfDay) // 调用DAO查询 val todayData = userDao.findUsersBornBetweenDates(fromDate, toDate)
2. 查询当周数据
可自行调整周起始规则,示例默认以周一为一周第一天,需改周日的话替换DayOfWeek.MONDAY为DayOfWeek.SUNDAY即可:
val now = LocalDate.now() // 本周起始(周一0点) val startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)) .atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() val fromDate = Date(startOfWeek) // 本周结束(周日最后一刻) val endOfWeek = now.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)) .atTime(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() val toDate = Date(endOfWeek) // 调用DAO查询 val weekData = userDao.findUsersBornBetweenDates(fromDate, toDate)
3. 查询当月数据
val now = LocalDate.now() // 当月第一天0点 val startOfMonth = now.with(TemporalAdjusters.firstDayOfMonth()) .atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() val fromDate = Date(startOfMonth) // 当月最后一天最后一刻 val endOfMonth = now.with(TemporalAdjusters.lastDayOfMonth()) .atTime(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() val toDate = Date(endOfMonth) // 调用DAO查询 val monthData = userDao.findUsersBornBetweenDates(fromDate, toDate)
旧Calendar API实现
如果暂时未开启脱糖支持,可使用Calendar类计算:
当日
val calendar = Calendar.getInstance() // 当日起始 calendar.set(Calendar.HOUR_OF_DAY, 0) calendar.set(Calendar.MINUTE, 0) calendar.set(Calendar.SECOND, 0) calendar.set(Calendar.MILLISECOND, 0) val fromDate = calendar.time // 当日结束 calendar.set(Calendar.HOUR_OF_DAY, 23) calendar.set(Calendar.MINUTE, 59) calendar.set(Calendar.SECOND, 59) calendar.set(Calendar.MILLISECOND, 999) val toDate = calendar.time
当周
val calendar = Calendar.getInstance() calendar.firstDayOfWeek = Calendar.MONDAY // 设置周一为一周起始 // 周起始 calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY) calendar.set(Calendar.HOUR_OF_DAY, 0) calendar.set(Calendar.MINUTE, 0) calendar.set(Calendar.SECOND, 0) calendar.set(Calendar.MILLISECOND, 0) val fromDate = calendar.time // 周结束 calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY) calendar.set(Calendar.HOUR_OF_DAY, 23) calendar.set(Calendar.MINUTE, 59) calendar.set(Calendar.SECOND, 59) calendar.set(Calendar.MILLISECOND, 999) val toDate = calendar.time
当月
val calendar = Calendar.getInstance() // 当月起始 calendar.set(Calendar.DAY_OF_MONTH, 1) calendar.set(Calendar.HOUR_OF_DAY, 0) calendar.set(Calendar.MINUTE, 0) calendar.set(Calendar.SECOND, 0) calendar.set(Calendar.MILLISECOND, 0) val fromDate = calendar.time // 当月结束 calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)) calendar.set(Calendar.HOUR_OF_DAY, 23) calendar.set(Calendar.MINUTE, 59) calendar.set(Calendar.SECOND, 59) calendar.set(Calendar.MILLISECOND, 999) val toDate = calendar.time
注意事项
- 所有时间计算统一使用相同时区,推荐默认使用设备系统时区,避免出现时差偏移问题
- 若查询结果不符合预期,可先打印
from和to的时间戳转成可读时间,核对时间范围是否正确
内容的提问来源于stack exchange,提问作者Zupermar
相关产品推荐
相关产品推荐

