如何检查NSDate
今天是否属于?
我曾经使用中的前10个字符来检查它[aDate description]
。[[aDate description] substringToIndex:10]
返回类似"YYYY-MM-DD"
的字符串,所以我将字符串与所返回的字符串进行了比较[[[NSDate date] description] substringToIndex:10]
。
有没有更快速和/或更整洁的检查方法?
谢谢。
如何检查NSDate
今天是否属于?
我曾经使用中的前10个字符来检查它[aDate description]
。[[aDate description] substringToIndex:10]
返回类似"YYYY-MM-DD"
的字符串,所以我将字符串与所返回的字符串进行了比较[[[NSDate date] description] substringToIndex:10]
。
有没有更快速和/或更整洁的检查方法?
谢谢。
Answers:
在macOS 10.9+和iOS 8+中,NSCalendar / Calendar上有一种方法可以做到这一点!
- (BOOL)isDateInToday:(NSDate *)date
所以你只要做
目标C:
BOOL today = [[NSCalendar currentCalendar] isDateInToday:date];
斯威夫特3:
let today = Calendar.current.isDateInToday(date)
您可以比较日期成分:
NSDateComponents *otherDay = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:aDate];
NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]];
if([today day] == [otherDay day] &&
[today month] == [otherDay month] &&
[today year] == [otherDay year] &&
[today era] == [otherDay era]) {
//do stuff
}
编辑:
我更喜欢stefan的方法,我认为它可以使if语句更简洁,更易理解:
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]];
NSDate *today = [cal dateFromComponents:components];
components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:aDate];
NSDate *otherDate = [cal dateFromComponents:components];
if([today isEqualToDate:otherDate]) {
//do stuff
}
克里斯,我已经采纳了你的建议。我必须查询一下什么时代,因此对于任何其他不知道的人,它可以区分BC和AD。对于大多数人来说,这可能是不必要的,但是它很容易检查并增加了确定性,因此我将其包括在内。如果您追求速度,那么这可能不是一个好方法。
注意,与SO上的许多答案一样,在7年后,这已经完全过时了。在Swift中,只需使用.isDateInToday
我将尝试将今天的日期归一化为午夜,将第二个日期归一化,归一化为午夜,然后比较是否是相同的NSDate。
在Apple的示例中,这是如何规范化到今天的午夜日期,对第二个日期执行相同的操作并进行比较:
NSCalendar * gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents * components =
[gregorian components:
(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit)
fromDate:[NSDate date]];
NSDate * today = [gregorian dateFromComponents:components];
无需费心处理组件,时代和事物。
NSCalendar提供了一种获取现有日期的特定时间单位的开始的方法。
该代码将获取今天的开始日期和另一个日期并将其进行比较。如果计算结果为NSOrderedSame
,则两个日期都在同一天-今天。
NSDate *today = nil;
NSDate *beginningOfOtherDate = nil;
NSDate *now = [NSDate date];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&today interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginningOfOtherDate interval:NULL forDate:beginningOfOtherDate];
if([today compare:beginningOfOtherDate] == NSOrderedSame) {
//otherDate is a date in the current day
}
extension NSDate {
func isToday() -> Bool {
let cal = NSCalendar.currentCalendar()
var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
let today = cal.dateFromComponents(components)!
components = cal.components([.Era, .Year, .Month, .Day], fromDate:self)
let otherDate = cal.dateFromComponents(components)!
return today.isEqualToDate(otherDate)
}
在Swift 2.0上为我工作
Swift版本的最佳答案:
let cal = NSCalendar.currentCalendar()
var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
let today = cal.dateFromComponents(components)!
components = cal.components([.Era, .Year, .Month, .Day], fromDate:aDate);
let otherDate = cal.dateFromComponents(components)!
if(today.isEqualToDate(otherDate)) {
//do stuff
}
请参阅Apple文档标题为“执行日历计算”的文档条目[link]。
该页面上的清单13建议使用以下方法确定两天之间的午夜数:
- (NSInteger)midnightsFromDate:(NSDate *)startDate toDate:(NSDate *)endDate
{
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSInteger startDay = [calendar ordinalityOfUnit:NSDayCalendarUnit
inUnit:NSEraCalendarUnit
forDate:startDate];
NSInteger endDay = [calendar ordinalityOfUnit:NSDayCalendarUnit
inUnit:NSEraCalendarUnit
forDate:endDate];
return endDay - startDay;
}
然后,您可以使用该方法确定两天是否相同,并查看它是否返回0。
您还可以检查您拥有的日期与当前日期之间的时间间隔:
[myDate timeIntervalSinceNow]
这将为您提供myDate和当前日期/时间之间的时间间隔(以秒为单位)。
链接。
编辑:所有人注意:我很清楚[myDate timeIntervalSinceNow]不会明确确定myDate是否是今天。
我将原样保留此答案,以便如果某人正在寻找相似的东西并且[myDate timeIntervalSinceNow]有用,他们可能会在这里找到。
timeIntervalSinceNow
它,因为它在许多其他职位中都涉及到。还可以通过比较秒数来处理日期比较,从而鼓励将错误易除以86400。– vikingosegundo 2014
Swift扩展基于最佳答案:
extension NSDate {
func isToday() -> Bool {
let cal = NSCalendar.currentCalendar()
if cal.respondsToSelector("isDateInToday:") {
return cal.isDateInToday(self)
}
var components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:NSDate())
let today = cal.dateFromComponents(components)!
components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:self);
let otherDate = cal.dateFromComponents(components)!
return today.isEqualToDate(otherDate)
}
}
如果您有很多这样的日期比较,则calendar:components:fromDate
开始通话会占用大量时间。根据我所做的一些分析,它们似乎非常昂贵。
假设您要尝试从某个日期数组(例如)确定哪个日期NSArray *datesToCompare
与给定日期(例如)的同一天NSDate *baseDate
,那么您可以使用类似以下内容的方法(部分改编自上述答案):
NSDate *baseDate = [NSDate date];
NSArray *datesToCompare = [NSArray arrayWithObjects:[NSDate date],
[NSDate dateWithTimeIntervalSinceNow:100],
[NSDate dateWithTimeIntervalSinceNow:1000],
[NSDate dateWithTimeIntervalSinceNow:-10000],
[NSDate dateWithTimeIntervalSinceNow:100000],
[NSDate dateWithTimeIntervalSinceNow:1000000],
[NSDate dateWithTimeIntervalSinceNow:50],
nil];
// determine the NSDate for midnight of the base date:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit)
fromDate:baseDate];
NSDate* theMidnightHour = [calendar dateFromComponents:comps];
// set up a localized date formatter so we can see the answers are right!
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
// determine which dates in an array are on the same day as the base date:
for (NSDate *date in datesToCompare) {
NSTimeInterval interval = [date timeIntervalSinceDate:theMidnightHour];
if (interval >= 0 && interval < 60*60*24) {
NSLog(@"%@ is on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]);
}
else {
NSLog(@"%@ is NOT on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]);
}
}
输出:
Nov 23, 2011 1:32:00 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:33:40 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:48:40 PM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 10:45:20 AM is on the same day as Nov 23, 2011 1:32:00 PM
Nov 24, 2011 5:18:40 PM is NOT on the same day as Nov 23, 2011 1:32:00 PM
Dec 5, 2011 3:18:40 AM is NOT on the same day as Nov 23, 2011 1:32:00 PM
Nov 23, 2011 1:32:50 PM is on the same day as Nov 23, 2011 1:32:00 PM
有比上述答案更简单的方法!
NSDate *date = ... // The date you wish to test
NSCalendar *calendar = [NSCalendar currentCalendar];
if([calendar isDateInToday:date]) {
//do stuff
}
这可能可以作为NSDate类别重做,但是我使用了:
// Seconds per day (24h * 60m * 60s)
#define kSecondsPerDay 86400.0f
+ (BOOL) dateIsToday:(NSDate*)dateToCheck
{
// Split today into components
NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents* comps = [gregorian components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit)
fromDate:[NSDate date]];
// Set to this morning 00:00:00
[comps setHour:0];
[comps setMinute:0];
[comps setSecond:0];
NSDate* theMidnightHour = [gregorian dateFromComponents:comps];
[gregorian release];
// Get time difference (in seconds) between date and then
NSTimeInterval diff = [dateToCheck timeIntervalSinceDate:theMidnightHour];
return ( diff>=0.0f && diff<kSecondsPerDay );
}
(但是,像原始问题中那样比较两个日期字符串几乎感觉“更干净”。)
comps
当立即将它们设置为零时,为什么要在创建时包括小时,分钟和秒?另外,我认为您需要包括时代。
对于iOS7和更早版本:
//this is now => need that for the current date
NSDate * now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSDateComponents * components = [calendar components:( NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate: now];
[components setMinute:0];
[components setHour:0];
[components setSecond:0];
//this is Today's Midnight
NSDate *todaysMidnight = [calendar dateFromComponents: components];
//now timeIntervals since Midnight => in seconds
NSTimeInterval todayTimeInterval = [now timeIntervalSinceDate: todaysMidnight];
//now timeIntervals since OtherDate => in seconds
NSTimeInterval otherDateTimeInterval = [now timeIntervalSinceDate: otherDate];
if(otherDateTimeInterval > todayTimeInterval) //otherDate is not in today
{
if((otherDateTimeInterval - todayTimeInterval) <= 86400) //86400 == a day total seconds
{
@"yesterday";
}
else
{
@"earlier";
}
}
else
{
@"today";
}
now = nil;
calendar = nil;
components = nil;
todaysMidnight = nil;
NSLog("Thank you :-)");
查看我们的Erica Sadun的出色表现NSDate extension
。使用非常简单。在这里精细:
http://github.com/erica/NSDate-Extensions
它已经在这篇文章中了:https : //stackoverflow.com/a/4052798/362310
在Swift 2.2以及iOS 8之前的版本中,无需强制解开的正确,安全的解决方案:
func isToday() -> Bool {
let calendar = NSCalendar.currentCalendar()
if #available(iOS 8.0, *) {
return calendar.isDateInToday(self)
}
let todayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:NSDate())
let dayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:self)
guard let today = calendar.dateFromComponents(todayComponents),
day = calendar.dateFromComponents(dayComponents) else {
return false
}
return today.compare(day) == .OrderedSame
}
这是我的2美分答案,基于公认的答案,但也支持较新的API。注意:由于大多数时间戳都是格林尼治标准时间,因此我使用公历,但请根据自己的喜好更改日历
func isDateToday(date: NSDate) -> Bool {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
if calendar.respondsToSelector("isDateInToday:") {
return calendar.isDateInToday(date)
}
let dateComponents = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay
let today = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: NSDate()))!
let dateToCompare = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: date))!
return dateToCompare == today
}
我的解决方案是按除法计算自1970年以来经过了多少天,并比较整数部分
#define kOneDay (60*60*24)
- (BOOL)isToday {
NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
NSInteger days =[self timeIntervalSince1970] + offset;
NSInteger currentDays = [[NSDate date] timeIntervalSince1970] + offset;
return (days / kOneDay == currentDays / kOneDay);
}
NSDate *dateOne = yourDate;
NSDate *dateTwo = [NSDate date];
switch ([dateOne compare:dateTwo])
{
case NSOrderedAscending:
NSLog(@”NSOrderedAscending”);
break;
case NSOrderedSame:
NSLog(@”NSOrderedSame”);
break;
case NSOrderedDescending:
NSLog(@”NSOrderedDescending”);
break;
}