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

如何不区分AM/PM检查时间段是否重叠(含±30分钟误差)

Solution for AM/PM-Agnostic Time Interval Overlap Check with ±30 Minute Tolerance

Got it, let's break down how to solve this problem. The key here is to eliminate AM/PM ambiguity entirely by mapping all times to a 12-hour cycle (0–719 minutes), then handle interval overlaps—including edge cases where intervals wrap around the 12-hour mark—while accounting for your ±30 minute tolerance.

Step 1: Normalize All Times to 12-Hour Cycle Minutes

First, convert every 24-hour time to its equivalent 12-hour cycle minute value. This removes AM/PM distinctions by taking the hour modulo 12, then calculating total minutes from the start of the 12-hour cycle:

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class TimeNormalizer {
    // Convert 24-hour time string (e.g., "13:45") to 12-hour cycle minutes
    public static int convert24hTo12hMinutes(String timeStr) {
        LocalTime time = LocalTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm"));
        int twelveHour = time.getHour() % 12;
        return twelveHour * 60 + time.getMinute();
    }
}

For example:

  • 01:00 → 60 minutes (1:00 in 12-hour)
  • 13:45 → 1*60 + 45 = 105 minutes (1:45 in 12-hour)
  • 23:00 → 11*60 = 660 minutes (11:00 in 12-hour)

Step 2: Define a 12-Hour Interval Class

Create a class to represent 12-hour intervals, including logic to handle intervals that wrap around the 12-hour mark (e.g., 11:00 PM → 1:00 AM becomes 660–60 minutes):

class TwelveHourInterval {
    private final int startMinutes; // 0–719
    private final int endMinutes;   // 0–719

    public TwelveHourInterval(int start, int end) {
        this.startMinutes = start % 720;
        this.endMinutes = end % 720;
    }

    // Check if the interval wraps around the 12-hour mark (e.g., 660–60)
    public boolean wrapsAroundTwelve() {
        return startMinutes > endMinutes;
    }

    // Expand the interval by ±30 minutes and split if it wraps around
    public List<int[]> getExtendedIntervals(int tolerance) {
        List<int[]> intervals = new ArrayList<>();
        int extendedStart = (startMinutes - tolerance + 720) % 720; // Avoid negative values
        int extendedEnd = (endMinutes + tolerance) % 720;

        if (!wrapsAroundTwelve() && extendedStart <= extendedEnd) {
            intervals.add(new int[]{extendedStart, extendedEnd});
        } else {
            // Split into two non-wrapping intervals
            intervals.add(new int[]{extendedStart, 720});
            intervals.add(new int[]{0, extendedEnd});
        }
        return intervals;
    }
}

Step 3: Overlap Check Logic

Write a utility to check if two extended intervals overlap. We need to compare all split intervals (for wrapping cases) to ensure we don't miss any overlaps:

public class OverlapChecker {
    private static final int TOLERANCE = 30; // ±30 minutes

    public static boolean hasOverlap(TwelveHourInterval interval1, TwelveHourInterval interval2) {
        List<int[]> extended1 = interval1.getExtendedIntervals(TOLERANCE);
        List<int[]> extended2 = interval2.getExtendedIntervals(TOLERANCE);

        // Check all combinations of extended intervals for overlap
        for (int[] int1 : extended1) {
            for (int[] int2 : extended2) {
                if (isNonWrappingOverlap(int1[0], int1[1], int2[0], int2[1])) {
                    return true;
                }
            }
        }
        return false;
    }

    // Check overlap between two non-wrapping intervals (start <= end)
    private static boolean isNonWrappingOverlap(int s1, int e1, int s2, int e2) {
        return s1 < e2 && s2 < e1;
    }
}

Step 4: Test with Your Example

Let's verify your use case:

public class Main {
    public static void main(String[] args) {
        // 1:00–3:00 (24h) → 60–180 minutes (12h)
        TwelveHourInterval interval1 = new TwelveHourInterval(
            TimeNormalizer.convert24hTo12hMinutes("01:00"),
            TimeNormalizer.convert24hTo12hMinutes("03:00")
        );

        // 13:45–14:45 (24h) → 105–165 minutes (12h)
        TwelveHourInterval interval2 = new TwelveHourInterval(
            TimeNormalizer.convert24hTo12hMinutes("13:45"),
            TimeNormalizer.convert24hTo12hMinutes("14:45")
        );

        // 3:15–4:00 (24h) → 195–240 minutes (12h)
        TwelveHourInterval interval3 = new TwelveHourInterval(
            TimeNormalizer.convert24hTo12hMinutes("03:15"),
            TimeNormalizer.convert24hTo12hMinutes("04:00")
        );

        System.out.println(OverlapChecker.hasOverlap(interval1, interval2)); // true (overlaps directly)
        System.out.println(OverlapChecker.hasOverlap(interval1, interval3)); // true (within 30min tolerance)
    }
}

Key Notes:

  • AM/PM Agnostic: By mapping all times to a 12-hour cycle, we don't care if a time is AM or PM—we only look at the 12-hour window.
  • Tolerance Handling: Expanding each interval by 30 minutes in both directions ensures that near-miss intervals (like 3:00 and 3:15) are counted as overlapping.
  • Wrapping Intervals: Splitting intervals that wrap around the 12-hour mark lets us use simple non-wrapping overlap logic for all comparisons.

内容的提问来源于stack exchange,提问作者user2511882

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 16:09:11