You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:36:03