如何确定多个(n)日期时间范围何时相互重叠

时间:2018-05-30 15:59:23

标签: ios objective-c swift

我正在寻找一个我可以调用的函数,它会告诉我所有(p)人同时可用的日期时间范围。 请帮我看看Objective-c或Swift语言。

p1: start: "2016-01-01 12:00", end: "2016-05-01 03:00"
p2: start: "2016-01-01 03:00", end: "2016-05-01 03:00"
p3: start: "2016-01-01 03:00", end: "2016-04-30 13:31"

在上面的例子中,答案应该是:

start: 2016-04-30 12:00, end: 2016-04-30 13:31

2 个答案:

答案 0 :(得分:6)

将您的日期对转换为NSDateInterval对象并获取它们的交集:

https://developer.apple.com/documentation/foundation/nsdateinterval/1641645-intersectionwithdateinterval

文档甚至提供了一个相当不错的图表:

enter image description here

答案 1 :(得分:2)

您需要执行以下步骤:

  1. 将日期字符串转换为Date对象。
  2. 使用开始和结束日期对象创建DateIntervals。
  3. 循环通过间隔并检查交叉点。
  4. 这是一个我可以在swift中提出的快速代码:

    func answer()  {
        let dateFormat = "yyyy-MM-dd HH:mm Z"
        // Date ranges
        let times = [["start": "2016-01-01 12:00 +0000", "end": "2016-05-01 03:00 +0000"],
                     ["start": "2016-01-01 03:00 +0000", "end": "2016-05-01 03:00 +0000"],
                     ["start": "2016-01-01 03:00 +0000", "end": "2016-04-30 13:31 +0000"]]
    
        var intervals = [DateInterval]()
        // Loop through date ranges to convert them to date intervals
        for item in times {
            if let start = convertStringToDate(string: item["start"]!, withFormat: dateFormat),
                let end = convertStringToDate(string: item["end"]!, withFormat: dateFormat) {
                intervals.append(DateInterval(start: start, end: end))
            }
        }
    
        // Check for intersection
        let intersection = intersect(intervals: intervals)
        print(intersection)
    }
    
    // Converts the string to date with given format
    func convertStringToDate(string: String, withFormat format: String)  -> Date? {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        return dateFormatter.date(from: string)
    }
    
    // Cehck for intersection among the intervals in the given array and return
        // the interval if found.
        func intersect(intervals: [DateInterval]) -> DateInterval? {
            // Algorithm:
            // We will compare first two intervals.
            // If an intersection is found, we will save the resultant interval
            // and compare it with the next interval in the array.
            // If no intersection is found at any iteration
            // it means the intervals in the array are disjoint. Break the loop and return nil
            // Otherwise return the last intersection.
    
            var previous = intervals.first
            for (index, element) in intervals.enumerated() {
                if index == 0 {
                    continue
                }
    
                previous = previous?.intersection(with: element)
    
                if previous == nil {
                    break
                }
            }
    
            return previous
        }
    

    注意:请使用多个示例进行测试。我测试了以上日期范围及其工作正常。