如何检查 NSDate 是否出现在两个其他 NSDate 之间
-
21-08-2019 - |
题
我试图确定当前日期是否在使用 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;
}
其他提示
对于第一部分,请使用以下答案 @kperryua 构造您想要比较的 NSDate 对象。从您对自己问题的回答来看,听起来您已经弄清楚了。
对于实际比较日期,我完全同意 @蒂姆对你的答案的评论。它更简洁,但实际上与您的代码完全相同,我将解释原因。
+ (BOOL) date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate {
return (([date compare:beginDate] != NSOrderedAscending) && ([date compare:endDate] != NSOrderedDescending));
}
尽管看起来 return 语句必须计算 && 运算符的两个操作数,但实际上并非如此。关键是“短路评估”,它可以用多种编程语言实现,当然还有 C。基本上,运营商 &
和 &&
如果第一个参数为 0(或 NO、nil 等),则为“短路”,而 |
和 ||
如果第一个参数是,则执行相同操作 不是 0。如果 date
出现在之前 beginDate
, ,测试返回 NO
甚至不需要比较 endDate
. 。基本上,它与您的代码执行相同的操作,但在一行的单个语句中,而不是 5 个(或 7 个,带空格)。
这旨在作为建设性输入,因为当程序员了解其特定编程语言评估逻辑表达式的方式时,他们可以更有效地构造它们,而无需过多考虑效率。但也有类似的测试 会 效率较低,因为并非所有操作员都会短路。(确实,大多数 不能 短路,例如数字比较运算符。)当有疑问时,明确地分解逻辑总是安全的,但是当您让语言/编译器为您处理小事情时,代码的可读性会更高。
布洛克伍尔夫版本在夫特:
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
}
}
如果你想知道,如果当前日期时间两个特定点之间的下降(上午9点 - 在09年7月1日下午5点),使用NSCalendar和NSDateComponents建立NSDate的实例为所需的时间,并与当前日期比较
如果你想知道如果当前日期落在这两个小时的每一个的一天,那么你很可能走另一条路。用和NSCalendar和您的NSDate创建NSDateComponents对象和比较小时组件。
此可以容易地使用的日期的时间间隔来实现,如下所示:
const NSTimeInterval i = [date timeIntervalSinceReferenceDate];
return ([startDate timeIntervalSinceReferenceDate] <= i &&
[endDate timeIntervalSinceReferenceDate] >= i);
与奎因的和Brock's解决方案继续,是非常好的继承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的:)
如果可以针对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
的DateInterval
方法:
let dateIsInInterval: Bool = dateInterval.contains(middle) // true
有针对此问题更好和更SWIFTY溶液。
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)
即使可以传递日期随机因为此分机检查哪一个是最小和其中在一个也没有。
可以在迅速3及以上使用。
使用夫特5,可以使用两种解决方案之一以下,以检查是否有其他两个日期之间发生的日期。
#1。使用DateInterval
的contains(_:)
方法
DateInterval
有一个称为方法 contains(_:)
。 contains(_:)
具有以下声明:
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
#2。使用ClosedRange
的contains(_:)
方法
ClosedRange
有一个称为方法 contains(_:)
。 contains(_:)
具有以下声明:
func contains(_ element: Bound) -> 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 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
}
}