简体   繁体   English

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

[英]How to determine when multiple(n) datetime ranges overlap each other

I'm looking for a function that I can call that will tell me what datetime ranges all (p) people are available at the same time. 我正在寻找一个可以调用的函数,该函数可以告诉我所有(p)个人同时可用的日期时间范围。 Please help me for Objective-c or Swift language. 请为我提供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"

In the above example the answer should be: 在以上示例中,答案应为:

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

Convert your pairs of dates to NSDateInterval objects and take their intersection: 将日期对转换为NSDateInterval对象,并采用它们的交集:

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

The docs even provide a rather nice diagram: 该文档甚至提供了一个相当不错的图表:

在此处输入图片说明

You need to do the following steps: 您需要执行以下步骤:

  1. Convert your date string to Date objects. 将您的日期字符串转换为Date对象。
  2. Create DateIntervals with your start and end date objects. 使用开始和结束日期对象创建DateIntervals。
  3. Loop through the intervals and check for intersection. 遍历区间并检查交叉点。

Here is a quick code I can come up with in 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
    }

Note: Please test with several examples. 注意:请通过几个示例进行测试。 I tested with above date ranges and its working fine. 我测试了上述日期范围及其工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM