Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 检查日期是否介于两个日期之间_Swift - Fatal编程技术网

Swift 检查日期是否介于两个日期之间

Swift 检查日期是否介于两个日期之间,swift,Swift,我有一个将字符串转换成日期对象的代码 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)

我有一个将字符串转换成日期对象的代码

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)          
}
我想知道当前日期是否介于我在数组中获得的两天之间
startdate
endate

Swift 2 有关更好的答案,请参阅

您已经有了将
keydata
中的日期字符串转换为
NSDate
的代码。假设您在
startdate
enddate
中有两个日期,您只需检查当前日期是否介于两者之间:

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
    }
}
敏捷的≧ 3. Swift 3让这变得容易多了

let fallsBetween = (startDate ... endDate).contains(Date())
既然
NSDate
被桥接到值类型
Date
,并且
Date
符合
Comparable
的要求,我们只需形成一个
ClosedRange
并使用
contains
方法查看是否包含当前日期

注意:
endDate
必须大于或等于
startDate
。否则无法形成范围,代码将崩溃,出现
fatalError

这是安全的:

extension Date {
    func isBetween(_ date1: Date, and date2: Date) -> Bool {
        return (min(date1, date2) ... max(date1, date2)).contains(self)
    }
}
延期日期{
func介于(日期1:date和日期2:date)->Bool之间{
返回日期1.timeIntervalSince1970self.timeIntervalSince1970
}
}

对于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)
let date = Date()
let date1 = Date(timeIntervalSinceNow: 1000)
let date2 = Date(timeIntervalSinceNow: -1000)
date.isBetween(date1, date2) // true
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)
    }
}

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

e、 g.从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
    }

}
延期日期{
func介于(uutdate:Date和endDate:Date)->Bool之间{

return startDate
DateInterval
有一个
。包含此()的
函数:

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

guard self != max(date1, date2) || self == min(date1, date2) else { return false }
经过一些重构后,您可以得到如下结果:

let myDateWithoutTime = Calendar.current.startOfDay(for: myDate)
let date = Date()
let date1 = Date(timeIntervalSinceNow: 1000)
let date2 = Date(timeIntervalSinceNow: -1000)
date.isBetween(date1, date2) // true
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))

这是一个很好的“把戏”,但也许应该补充一点,这检查“严格介于之间”,即不包括开始和结束日期(可能需要也可能不需要)@NikolaiRuhe嘿,谢谢你的回答,但是你解决了Martin R note吗?我也面临同样的问题,开始日期和结束日期是相同的,所以当我遵循你的回答时,这个范围没有返回真值。用这种方式依赖
NSComparisonResult
的基本值可能不是最安全的。它是
Int
>值,因为Objective-C使用枚举,而Objective-C只允许整数类型的枚举。将原始值相乘将假定为欠序整数的值,我认为这是不能保证的。@Abizern我同意以这种方式使用原始值有点模糊。另一方面,如何不保证这些值的精确性
-1
0
+1
?文档和标题清楚地定义了整数值。如果
NSComparisonResult
的值在某一点上发生更改,许多代码将中断。@Abizern我同意第二个包含检查的代码示例太模糊了。可能值得编辑您以前的ac接受这个答案。这太好了!@XcodeNOOB:对我有用。Swift的
ClosedRange
包含
语义意味着开始和结束日期都是包含的:
(startDate…endDate)。包含(startDate)=true
(startDate…endDate)。包含(endDate)==true
。只是一个警告,如果startDate晚于endDate,应用程序将崩溃。除非您100%确定永远不会发生这种情况,否则您可能需要添加
guard startDate
Sorry@leviathan,但我发现您的编辑包含了太多的代码,分散了Swift解决方案的简单性。我添加了一条注释,以我的方式解释问题。
date1…date2~=self
?这有什么问题吗?