【问题标题】:Check if date falls between 2 dates检查日期是否在两个日期之间
【发布时间】:2015-09-30 06:48:36
【问题描述】:

我有这段代码将字符串转换为日期对象

let date2 = KeysData[indexPath.row]["starttime"] as? String

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

if let date = dateFormatter.dateFromString(date2!) {
   println(date)          
}

我想知道当前日期是否介于数组startdateendate 中的两天之间

【问题讨论】:

    标签: swift


    【解决方案1】:

    斯威夫特≧3

    Swift 3 让这变得容易多了。

    let fallsBetween = (startDate ... endDate).contains(Date())
    

    现在NSDate 桥接到Date 的值类型并且Date 符合Comparable 我们可以只形成一个ClosedRange<Date> 并使用contains 方法来查看是否包含当前日期。

    警告:endDate 必须大于或等于 startDate。否则无法形成范围,代码会以fatalError 崩溃。

    这是安全的:

    extension Date {
        func isBetween(_ date1: Date, and date2: Date) -> Bool {
            return (min(date1, date2) ... max(date1, date2)).contains(self)
        }
    }
    

    【讨论】:

    • 可能值得编辑您之前接受的答案。这太棒了!
    • @XcodeNOOB:对我有用。 Swift 的 ClosedRangecontains 语义意味着开始和结束日期都包含在内:(startDate...endDate).contains(startDate) == true(startDate...endDate).contains(endDate) == true
    • 只是一个警告,如果 startDate 永远晚于 endDate 应用程序将崩溃。除非您 100% 确定永远不会出现这种情况,否则您可能需要添加 guard startDate < endDate else {...}
    • 对不起@leviathan,但我发现您的编辑包含太多代码,分散了 Swift 解决方案的简单性。我添加了一条注释,以我的方式解释了问题。
    • date1...date2 ~= self?
    【解决方案2】:

    斯威夫特 2

    如需更好的答案,请参阅Swift ≧ 3

    您已经拥有将KeysData 中的日期字符串转换为NSDate 的代码。假设您在startdateenddate 中有两个日期,您所要做的就是检查当前日期是否介于两者之间:

    let startDate = ...
    let endDate = ...
    
    NSDate().isBetween(date: startDate, andDate: endDate)
    
    extension NSDate {
        func isBetweeen(date date1: NSDate, andDate date2: NSDate) -> Bool {
            return date1.compare(self) == self.compare(date2)
        }
    }
    

    编辑:如果要执行包含范围检查,请使用以下条件:

     extension NSDate {
        func isBetween(date date1: NSDate, andDate date2: NSDate) -> Bool {
            return date1.compare(self).rawValue * self.compare(date2).rawValue >= 0
        }
    }
    

    【讨论】:

    • 这是一个很好的“技巧”,但也许应该补充一点,这会检查“严格介于”之间,即不包括开始日期和结束日期(可能需要也可能不需要)。跨度>
    • @NikolaiRuhe 嘿,谢谢你的回答,但是你解决了 Martin R 笔记吗?我也遇到了同样的问题,开始日期和结束日期是相同的日期,所以当我按照你的回答时,这个铃声没有返回 true
    • 以这种方式依赖NSComparisonResult 的潜在价值可能不是最安全的事情。这是一个Int 值,因为该枚举由Objective-C 使用,它只允许整数类型的枚举。将原始值相乘会假设下整数的值,我认为这不能保证。
    • @Abizern 我同意以这种方式使用原始值有点混淆。另一方面:如何不能保证这些值完全是-10+1?文档和标题清楚地定义了整数值。如果NSComparisonResult 的值在某个时候发生变化,很多代码都会中断。
    • @Abizern 我同意带有包容性检查的第二个代码示例过于模糊。
    【解决方案3】:

    对于 Swift 4.2+,我根据上面的答案使用了这个扩展:

    extension Date {
        func isBetween(_ date1: Date, and date2: Date) -> Bool {
            return (min(date1, date2) ... max(date1, date2)) ~= self
        }
    }
    

    但要小心。如果此扩展不包括您的开始日期 (date1),请检查您的日期时间。可能您需要从日期中缩短时间来修复它。例如,像这样:

    let myDateWithoutTime = Calendar.current.startOfDay(for: myDate)
    

    【讨论】:

      【解决方案4】:
      extension Date
      {
          func isBetween(startDate:Date, endDate:Date)->Bool
          {
               return (startDate.compare(self) == .orderedAscending) && (endDate.compare(self) == .orderedDescending)
          }
      }
      

      【讨论】:

        【解决方案5】:

        这里没有一个答案明确涵盖可能更精确的边界测试,它们在开始和结束之间有所不同。

        例如从 0900 开始到 1000 结束的事件应该有返回以下结果的案例:

        08:59:59    false
        09:00:00    true
        09:59:59    true
        10:00:00    false
        

        如果这是您想要的结果,那么以下扩展将适合您:

        extension Date {
        
            func isBetween(_ startDate: Date, and endDate: Date) -> Bool {
                return startDate <= self && self < endDate
            }
        
        }
        

        【讨论】:

          【解决方案6】:

          DateInterval 对此有一个 .contains 函数 (see docs):

          extension Date {
              func isBetween(_ date1: Date, _ date2: Date) -> Bool {
                  date1 < date2
                      ? DateInterval(start: date1, end: date2).contains(self)
                      : DateInterval(start: date2, end: date1).contains(self)
              }
          }
          

          然后你这样使用它:

          let date = Date()
          let date1 = Date(timeIntervalSinceNow: 1000)
          let date2 = Date(timeIntervalSinceNow: -1000)
          date.isBetween(date1, date2) // true
          

          如果您需要,请注意包括结束日期,或者添加 guard 来捕获它:

          guard self != max(date1, date2) || self == min(date1, date2) else { return false }
          

          经过一些重构后,您可以得到如下结果:

          extension Date {
              func isBetween(_ date1: Date, _ date2: Date) -> Bool {
                  let minDate = min(date1, date2)
                  let maxDate = max(date1, date2)
          
                  guard self != minDate else { return true }
                  guard self != maxDate else { return false }
          
                  return DateInterval(start: minDate, end: maxDate).contains(self)
              }
          }
          

          那么这将通过以下测试用例:

          XCTAssert(
              try XCTUnwrap(Date(fromString: "2020/01/15 09:30")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 09:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00"))
              )
          )
          
          XCTAssert(
              try XCTUnwrap(Date(fromString: "2020/01/16 01:00")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 23:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/16 04:00"))
              )
          )
          
          XCTAssert(
              try XCTUnwrap(Date(fromString: "2020/01/15 10:00")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:30"))
              )
          )
          
          XCTAssert(
              try XCTUnwrap(Date(fromString: "2020/01/15 10:00")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00"))
              )
          )
          
          XCTAssert(
              try XCTUnwrap(Date(fromString: "2020/01/15 09:00")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/15 08:00"))
              )
          )
          
          XCTAssert(
              try XCTUnwrap(Date(fromString: "2020/01/15 08:00")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/15 08:00"))
              )
          )
          
          XCTAssertFalse(
              try XCTUnwrap(Date(fromString: "2020/01/15 09:00")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/15 13:00"))
              )
          )
          
          XCTAssertFalse(
              try XCTUnwrap(Date(fromString: "2020/01/15 10:30")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:30"))
              )
          )
          
          XCTAssertFalse(
              try XCTUnwrap(Date(fromString: "2020/01/15 10:00")).isBetween(
                  try XCTUnwrap(Date(fromString: "2020/01/15 10:00")),
                  try XCTUnwrap(Date(fromString: "2020/01/15 08:00"))
              )
          )
          
          let date = Date()
          let date1 = Date(timeIntervalSinceNow: 1000)
          let date2 = Date(timeIntervalSinceNow: -1000)
          XCTAssert(date.isBetween(date1, date2))
          

          【讨论】:

            【解决方案7】:
            extension Date {
            
                func isBetweeen(date date1: Date, andDate date2: Date) -> Bool {
                    return date1.timeIntervalSince1970 < self.timeIntervalSince1970 && date2.timeIntervalSince1970 > self.timeIntervalSince1970
                }
            
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-04-11
              • 2012-09-19
              • 2017-07-07
              • 2016-05-31
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多