我正在尝试使用NSDate确定当前日期是否在日期范围内。
例如,您可以使用NSDate获取当前日期/时间:
NSDate rightNow = [NSDate date];
我希望使用那个日期来检查它是否在上午9点至下午5点的范围内。
我正在尝试使用NSDate确定当前日期是否在日期范围内。
例如,您可以使用NSDate获取当前日期/时间:
NSDate rightNow = [NSDate date];
我希望使用那个日期来检查它是否在上午9点至下午5点的范围内。
我想出了一个解决方案。如果您有更好的解决方案,请随意留下来,我会将其标记为正确答案。
+ (BOOL)date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate
{
if ([date compare:beginDate] == NSOrderedAscending)
return NO;
if ([date compare:endDate] == NSOrderedDescending)
return NO;
return YES;
}
- (BOOL)isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate;
。 - Matteo Alessanireturn !([date compare:startDate] == NSOrderedAscending || [date compare:endDate] == NSOrderedDescending);
- Gabriele Petronella首先,使用@kperryua的答案构建你想要比较的NSDate对象。从你对自己问题的回答来看,你好像已经想到了这一点。
对于实际比较日期,我完全同意@Tim在你的问题上的评论。它更加简洁,但实际上与你的代码完全相同,我将解释为什么。
+ (BOOL) date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {
return (([date compare:beginDate] != NSOrderedAscending) && ([date compare:endDate] != NSOrderedDescending));
}
&
和&&
会"短路",而如果第一个参数不是0,则|
和||
也会这样做。如果date
在beginDate
之前,则测试返回NO
,甚至不需要与endDate
进行比较。基本上,它执行与您的代码相同的操作,但在一行上以单个语句的形式执行,而不是5行(或7行,包括空格)。用Swift编写的Brock Woolf版本:
extension NSDate
{
func isBetweenDates(beginDate: NSDate, endDate: NSDate) -> Bool
{
if self.compare(beginDate) == .OrderedAscending
{
return false
}
if self.compare(endDate) == .OrderedDescending
{
return false
}
return true
}
}
如果您的目标是 iOS 10.0+/macOS 10.12+,那么可以使用 DateInterval
类。
首先,使用起始日期和结束日期创建一个日期区间:
let start: Date = Date()
let middle: Date = Date()
let end: Date = Date()
let dateInterval: DateInterval = DateInterval(start: start, end: end)
接下来,使用 DateInterval
的 contains
方法检查日期是否在间隔内:
let dateIsInInterval: Bool = dateInterval.contains(middle) // true
继续Quinn和Brock的解决方案,很好地子类化NSDate实现,以便可以在任何地方像这样使用:
-(BOOL) isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {
return (([self compare:beginDate] != NSOrderedAscending) && ([self compare:endDate] != NSOrderedDescending));
}
在你的代码的任何部分,你都可以这样使用它:
[myNSDate isBetweenDate:thisNSDate andDate:thatNSDate];
可以使用日期时间间隔轻松实现此操作,例如:
const NSTimeInterval i = [date timeIntervalSinceReferenceDate];
return ([startDate timeIntervalSinceReferenceDate] <= i &&
[endDate timeIntervalSinceReferenceDate] >= i);
针对这个问题,有更好、更快捷的解决方案。
extention Date {
func isBetween(from startDate: Date,to endDate: Date) -> Bool {
let result = (min(startDate, endDate) ... max(startDate, endDate)).contains(self)
return result
}
}
todayDate.isBetween(from: startDate, to: endDate)
即使您随机传递日期,该扩展程序也会检查哪个日期最小,哪个日期不是。
您可以在Swift 3及以上版本中使用它。
使用Swift 5,您可以使用以下两种解决方案之一来检查日期是否在另外两个日期之间。
DateInterval
的contains(_:)
方法DateInterval
有一个名为contains(_:)
的方法。 contains(_:)
具有以下声明:
func contains(_ date: Date) -> Bool
指示此时间间隔是否包含给定日期。
以下Playground代码展示了如何使用contains(_:)
来检查一个日期是否在另外两个日期之间:
import Foundation
let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let myDate = calendar.date(from: DateComponents(year: 2012, month: 8, day: 15))!
let dateInterval = DateInterval(start: startDate, end: endDate)
let result = dateInterval.contains(myDate)
print(result) // prints: true
ClosedRange
的 contains(_:)
方法ClosedRange
有一个叫做 contains(_:)
的方法。 contains(_:)
的声明如下:
func contains(_ element: Bound) -> Bool
返回一个布尔值,指示给定元素是否包含在范围内。
以下Playground代码展示了如何使用contains(_:)
来检查一个日期是否在另外两个日期之间:
import Foundation
let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let myDate = calendar.date(from: DateComponents(year: 2012, month: 8, day: 15))!
let range = startDate ... endDate
let result = range.contains(myDate)
//let result = range ~= myDate // also works
print(result) // prints: true
@objc public class DateRange: NSObject {
let startDate: Date
let endDate: Date
init(startDate: Date, endDate: Date) {
self.startDate = startDate
self.endDate = endDate
}
@objc(containsDate:)
func contains(_ date: Date) -> Bool {
let startDateOrder = date.compare(startDate)
let endDateOrder = date.compare(endDate)
let validStartDate = startDateOrder == .orderedAscending || startDateOrder == .orderedSame
let validEndDate = endDateOrder == .orderedDescending || endDateOrder == .orderedSame
return validStartDate && validEndDate
}
}