Android minSdkVersion 22下判断时间在当前前后区间的跨天问题求解
实现方案
以下两种方案均兼容minSdk 22,无需额外依赖或开启desugar适配:
方案1:时分转当日毫秒数 + 环形区间判断
适合待校验时间仅有时分、没有日期信息的场景,核心逻辑是把时间转为当日0点开始的总毫秒数,按环形区间处理跨天场景:
/** * 判断指定时间是否在当前时间前30分钟到后20分钟区间内 * @param checkHour 待校验时间的小时(24小时制) * @param checkMinute 待校验时间的分钟 * @return 符合区间返回true,否则返回false */ private boolean isTimeInRange(int checkHour, int checkMinute) { final long ONE_DAY_MS = 24 * 60 * 60 * 1000L; final long BEFORE_RANGE_MS = 30 * 60 * 1000L; final long AFTER_RANGE_MS = 20 * 60 * 1000L; // 当前时间转当日毫秒数 Calendar now = Calendar.getInstance(); int nowHour = now.get(Calendar.HOUR_OF_DAY); int nowMinute = now.get(Calendar.MINUTE); long nowMs = (nowHour * 60L + nowMinute) * 60 * 1000; // 计算区间起止毫秒数,加一天再取模避免负数 long startMs = (nowMs - BEFORE_RANGE_MS + ONE_DAY_MS) % ONE_DAY_MS; long endMs = (nowMs + AFTER_RANGE_MS) % ONE_DAY_MS; // 待校验时间转当日毫秒数 long checkMs = (checkHour * 60L + checkMinute) * 60 * 1000; // 区间判断 if (startMs < endMs) { // 未跨天,直接判断是否在两个值之间 return checkMs >= startMs && checkMs <= endMs; } else { // 跨天,大于起始值或小于结束值都符合 return checkMs >= startMs || checkMs <= endMs; } }
验证示例:
- 示例1:当前23:45,startMs为23:15对应的毫秒数、endMs为00:05对应的毫秒数,
startMs>endMs,23:50的毫秒数大于startMs,返回true - 示例2:当前00:05,startMs为23:35对应的毫秒数、endMs为00:25对应的毫秒数,
startMs>endMs,00:15的毫秒数小于endMs,返回true
方案2:完整时间戳比较
如果待校验时间包含日期信息,或需要支持跨多天的判断场景,推荐直接用时间戳比较,完全规避跨天逻辑:
/** * @param checkTimestamp 待校验时间的毫秒级时间戳 */ private boolean isTimeInRange(long checkTimestamp) { long now = System.currentTimeMillis(); long startTime = now - 30 * 60 * 1000L; long endTime = now + 20 * 60 * 1000L; return checkTimestamp >= startTime && checkTimestamp <= endTime; }
如果待校验时间只有时分,可以手动补全日期后再判断:
private boolean isTimeInRange(int checkHour, int checkMinute) { Calendar now = Calendar.getInstance(); // 构造待校验时间,默认使用当前日期 Calendar checkCal = Calendar.getInstance(); checkCal.set(Calendar.HOUR_OF_DAY, checkHour); checkCal.set(Calendar.MINUTE, checkMinute); checkCal.set(Calendar.SECOND, 0); checkCal.set(Calendar.MILLISECOND, 0); long checkTime = checkCal.getTimeInMillis(); long nowTime = now.getTimeInMillis(); long startTime = nowTime - 30 * 60 * 1000L; long endTime = nowTime + 20 * 60 * 1000L; // 自动调整跨天的日期偏移 if (checkTime - endTime > 12 * 60 * 60 * 1000L) { // 待校验时间比结束时间大半天以上,说明是前一天的时间 checkCal.add(Calendar.DAY_OF_MONTH, -1); checkTime = checkCal.getTimeInMillis(); } else if (startTime - checkTime > 12 * 60 * 60 * 1000L) { // 待校验时间比开始时间小半天以上,说明是后一天的时间 checkCal.add(Calendar.DAY_OF_MONTH, 1); checkTime = checkCal.getTimeInMillis(); } return checkTime >= startTime && checkTime <= endTime; }
内容的提问来源于stack exchange,提问作者TaoTao
相关产品推荐
相关产品推荐

