我正在尝试使用NSDate判断当前日期是否在日期范围内。
例如,您可以使用NSDate获取当前日期/时间:
NSDate rightNow = [NSDate date];
我希望使用该日期来检查它是否在上午9点 - 下午5点的范围内。
答案 0 :(得分:161)
我想出了一个解决方案。如果您有更好的解决方案,请随意离开,我会将其标记为正确。
+ (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;
}
答案 1 :(得分:14)
对于第一部分,使用 @kperryua 中的答案来构造要与之比较的NSDate对象。根据你对自己问题的回答,听起来你已经弄明白了。
为了实际比较日期,我完全同意 @Tim 对你的答案的评论。它更简洁但实际上完全等同于您的代码,我将解释原因。
+ (BOOL) date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {
return (([date compare:beginDate] != NSOrderedAscending) && ([date compare:endDate] != NSOrderedDescending));
}
虽然看起来似乎return语句必须评估&&和&运营商,实际情况并非如此。关键是“short-circuit evaluation”,它以各种编程语言实现,当然在C语言中实现。基本上,运算符 &
和 {{1 }} 如果第一个参数为0(或NO,nil等),则为“短路”,而 &&
和 |
如果第一个参数不 0,则执行相同操作。如果||
在date
之前,则测试返回beginDate
,甚至不需要与{NO
进行比较1}}。基本上,它与您的代码完全相同,但在一行中的单个语句中,而不是5(或7,具有空格)。
这是作为建设性的输入,因为当程序员理解他们的特定编程语言评估逻辑表达式的方式时,他们可以更有效地构建它们而不需要太多关于效率。但是,有类似的测试 效率较低,因为并非所有运营商都会短路。 (实际上,大多数不能短路,例如数值比较运算符。)如果有疑问,明确分解你的逻辑总是安全的,但是当你放弃时,代码可以更加可读语言/编译器为你处理小事。
答案 2 :(得分:8)
Swift中的Brock Woolf版本:
var
答案 3 :(得分:5)
如果您想知道当前日期是否在两个给定时间点之间(2009年7月1日上午9点至下午5点),请使用NSCalendar和NSDateComponents构建所需时间的NSDate实例,并将它们与当前日期进行比较
如果您想知道当前日期是否在每天这两个小时之间,那么您可能会采取相反的方式。使用和NSCalendar以及NSDate创建NSDateComponents对象并比较小时组件。
答案 4 :(得分:4)
这可以使用日期的时间间隔轻松完成,如下所示:
const NSTimeInterval i = [date timeIntervalSinceReferenceDate];
return ([startDate timeIntervalSinceReferenceDate] <= i &&
[endDate timeIntervalSinceReferenceDate] >= i);
答案 5 :(得分:3)
继续使用Quinn和Brock的解决方案,非常适合继承NSDate实现,所以它可以在任何地方使用:
-(BOOL) isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {
return (([self compare:beginDate] != NSOrderedAscending) && ([self compare:endDate] != NSOrderedDescending));
}
在代码的任何部分,您都可以将其用作:
[myNSDate isBetweenDate:thisNSDate andDate:thatNSDate];
(myNSDate,thisNSDate和thatNSDate当然是NSDates :)
答案 6 :(得分:2)
如果您可以定位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)
然后,使用contains
的{{1}}方法检查日期是否在间隔中:
DateInterval
答案 7 :(得分:2)
这个问题有更好,更快捷的解决方案。
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及以上版本中使用它。
答案 8 :(得分:0)
Swift中更好的版本:
@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
}
}
答案 9 :(得分:0)
使用Swift 4.2和iOS 12,您可以使用以下两种解决方案之一来检查某个日期是否在其他两个日期之间。
DateInterval
的{{1}}方法 contains(_:)
有一个称为contains(_:)
的方法。 DateInterval
具有以下声明:
contains(_:)
指示此间隔是否包含给定日期。
以下Playground代码显示了如何使用func contains(_ date: Date) -> Bool
来检查某个日期是否在其他两个日期之间:
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
的{{1}}方法 ClosedRange
有一个称为contains(_:)
的方法。 contains(_:)
具有以下声明:
ClosedRange
返回一个布尔值,指示给定元素是否包含在范围内。
以下Playground代码显示了如何使用contains(_:)
来检查某个日期是否在其他两个日期之间:
func contains(_ element: Bound) -> Bool