如何在Objective-C中比较两个日期


70

我有两个日期:2009-05-11和当前日期。我想检查给定的日期是否是当前日期。这怎么可能。


查看答案,尚不清楚是要字面上比较两个NSDate实例是否相等(同一时间点),还是想知道它们是否在同一日历日。
Nikolai Ruhe 2015年

Answers:


156

可可有两种方法

在NSDate

isEqualToDate:  
– earlierDate:  
– laterDate:  
– compare:

使用时- (NSComparisonResult)compare:(NSDate *)anotherDate,您可以返回以下其中一项:

The receiver and anotherDate are exactly equal to each other, NSOrderedSame
The receiver is later in time than anotherDate, NSOrderedDescending
The receiver is earlier in time than anotherDate, NSOrderedAscending.

例:

NSDate * now = [NSDate date];
NSDate * mile = [[NSDate alloc] initWithString:@"2001-03-24 10:45:32 +0600"];
NSComparisonResult result = [now compare:mile];

NSLog(@"%@", now);
NSLog(@"%@", mile);

switch (result)
{
    case NSOrderedAscending: NSLog(@"%@ is in future from %@", mile, now); break;
    case NSOrderedDescending: NSLog(@"%@ is in past from %@", mile, now); break;
    case NSOrderedSame: NSLog(@"%@ is the same as %@", mile, now); break;
    default: NSLog(@"erorr dates %@, %@", mile, now); break;
}

[mile release];

1
这如何回答“给定日期是否是当前日期”这一原始问题?[NSDate date]将与所有固定日期都NSOrderedSame相同,而不是24小时,但不超过一秒。
卫生经济研究所

这不适用于iOS。查看接受的答案:stackoverflow.com/questions/14702626/...
挪威的亚历山大

@HappyFlow问题被标记为cocoa它没有提到iOS,有关更多信息,请尝试使用Google“ cocoa” vs“ cocoa touch”
stefanB 2013年

@stefanB我不好,我没看到。
挪威亚历山大(Alexander of Norway)

@AlexanderofNorway根据苹果文档,这确实适用于iOS自iOS2.0起:developer.apple.com/library/ios/documentation/Cocoa/Reference/…
阿尔伯特·伦肖

44

哥们 此功能会将您的日期与任何特定日期匹配,并能够判断它们是否匹配。您还可以修改组件以符合您的要求。

- (BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 {
NSCalendar* calendar = [NSCalendar currentCalendar];

unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];

return [comp1 day]   == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year]  == [comp2 year];}

问候,Naveed屁股


3
这是正确的答案。虽然最佳答案可能更笼统,但这提供了针对所出现问题的解决方案。
elsurudo

2
刚刚好!!
正在尝试几种

2
@Naveed Rafi这是我享受其服务两年来在StackOverflow上看到的最精确和最有用的答案。
西蒙

40
NSDate *today = [NSDate date]; // it will give you current date
NSDate *newDate = [NSDate dateWithString:@"xxxxxx"]; // your date 

NSComparisonResult result; 
//has three possible values: NSOrderedSame,NSOrderedDescending, NSOrderedAscending

result = [today compare:newDate]; // comparing two dates

if(result==NSOrderedAscending)
    NSLog(@"today is less");
else if(result==NSOrderedDescending)
    NSLog(@"newDate is less");
else
    NSLog(@"Both dates are same");

您可以使用其他方法来比较NSDate对象。每种方法在某些任务上将更加有效。我选择了compare方法,因为它可以处理您大多数的基本日期比较需求。


32

类别提供了一种比较NSDate的巧妙方法:

#import <Foundation/Foundation.h>

@interface NSDate (Compare)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
//- (BOOL)isEqualToDate:(NSDate *)date; already part of the NSDate API

@end

并执行:

#import "NSDate+Compare.h"

@implementation NSDate (Compare)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedAscending);
}

-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedDescending);

}
-(BOOL) isEarlierThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedAscending);
}

@end

使用简单:

if([aDateYouWantToCompare isEarlierThanOrEqualTo:[NSDate date]]) // [NSDate date] is now
{
    // do your thing ...
}

1
谢谢!这比直接在其中包含带有NSComparisonResults的代码(日期难以理解)要好得多。
Dan Rosenstark 2014年

1
苹果应该考虑实施此方法。比为早于或等于或晚于或等于的开关语句创建开关要容易得多。
geekinit '16

23

如果您同时创建两个日期NSDate,则可以使用NSDatecompare:方法:

NSComparisonResult result = [Date2 compare:Date1];

if(result==NSOrderedAscending)
    NSLog(@"Date1 is in the future");
else if(result==NSOrderedDescending)
    NSLog(@"Date1 is in the past");
else
    NSLog(@"Both dates are the same");

您可以在这里查看文档。


15

通过这种方法,您还可以比较两个日期

NSDate * dateOne = [NSDate date];
NSDate * dateTwo = [NSDate date];

if([dateOne compare:dateTwo] == NSOrderedAscending)
{

}

2
有趣的常量与力量对比是:NSOrderedAscendingNSOrderedSameNSOrderedDescending,但OP可能想NSOrderedSame为他的特殊问题。
克里斯(Kris)

9

我发现最好的方法是检查给定日期与今天之间的时差:

NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* now = [NSDate date];
int differenceInDays =
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] -
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now];

根据苹果的《日期和时间编程指南》中日历计算清单13 [NSCalendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:myDate],您可以得出自时代开始以来的午夜数。这样,很容易检查日期是昨天,今天还是明天。

switch (differenceInDays) {
    case -1:
        dayString = @"Yesterday";
        break;
    case 0:
        dayString = @"Today";
        break;
    case 1:
        dayString = @"Tomorrow";
        break;
    default: {
        NSDateFormatter* dayFormatter = [[NSDateFormatter alloc] init];
        [dayFormatter setLocale:usLocale];
        [dayFormatter setDateFormat:@"dd MMM"];
        dayString = [dayFormatter stringFromDate: date];
        break;
    }
}

4
NSDateFormatter *df= [[NSDateFormatter alloc] init];

[df setDateFormat:@"yyyy-MM-dd"];

NSDate *dt1 = [[NSDate alloc] init];

NSDate *dt2 = [[NSDate alloc] init];

dt1=[df dateFromString:@"2011-02-25"];

dt2=[df dateFromString:@"2011-03-25"];

NSComparisonResult result = [dt1 compare:dt2];

switch (result)
{

        case NSOrderedAscending: NSLog(@"%@ is greater than %@", dt2, dt1); break;

        case NSOrderedDescending: NSLog(@"%@ is less %@", dt2, dt1); break;

        case NSOrderedSame: NSLog(@"%@ is equal to %@", dt2, dt1); break;

        default: NSLog(@"erorr dates %@, %@", dt2, dt1); break;

}

享受编码……


3


1

这是Pascal答案的Swift变体:

extension NSDate {

    func isLaterThanOrEqualTo(date:NSDate) -> Bool {
        return !(self.compare(date) == NSComparisonResult.OrderedAscending)
    }

    func isEarlierThanOrEqualTo(date:NSDate) -> Bool {
        return !(self.compare(date) == NSComparisonResult.OrderedDescending)
    }

    func isLaterThan(date:NSDate) -> Bool {
        return (self.compare(date) == NSComparisonResult.OrderedDescending)
    }

    func isEarlierThan(date:NSDate) -> Bool {
        return (self.compare(date) == NSComparisonResult.OrderedAscending)
    }
}

可以用作:

self.expireDate.isEarlierThanOrEqualTo(NSDate())

1

如果有人在寻找,这是Naveed Rafi的答案中的函数转换为Swift:

func isSameDate(#date1: NSDate, date2: NSDate) -> Bool {
    let calendar = NSCalendar()
    let date1comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date1)
    let date2comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date2)
    return (date1comp.year == date2comp.year) && (date1comp.month == date2comp.month) && (date1comp.day == date2comp.day)
}

0
Get Today's Date:

NSDate* date = [NSDate date];

Create a Date From Scratch:    
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.year = 2015;
comps.month = 12;
comps.day = 31;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* date = [calendar dateFromComponents:comps];


Add a day to a Date:  
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = 1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* tomorrow = [calendar dateByAddingComponents:comps toDate:date options:nil];


Subtract a day from a Date:    
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = -1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* yesterday = [calendar dateByAddingComponents:comps toDate:date options:nil];



Convert a Date to a String:  

NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = @"MMMM dd, yyyy";
NSString* dateString = [formatter stringFromDate:date];


Convert a String to a Date:

NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = @"MMMM dd, yyyy";
NSDate* date = [formatter dateFromString:@"August 02, 2014"];


Find how many days are in a month:    
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSRange currentRange = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
NSInteger numberOfDays = currentRange.length;


Calculate how much time something took:   

NSDate* start = [NSDate date];
for(int i = 0; i < 1000000000; i++);
NSDate* end = [NSDate date];
NSTimeInterval duration = [end timeIntervalSinceDate:start];


Find the Day Of Week for a specific Date:

NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSInteger dow = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];

然后使用NSComparisonResult比较日期。


-3

..

NSString *date = @"2009-05-11"
NSString *nowDate = [[[NSDate date]description]substringToIndex: 10];
if([date isEqualToString: nowDate])
{
// your code
}

2
我认为将“日期”转换为NSDate对象,然后比较NSDate对象会更加有用。这段代码可以工作,但是substringToIndex:10确实是一个hack。如果您需要更多信息,例如最近的日期-您也需要这样做。
Ben Gotow 09年

当然,您可以比较NSDate对象。但是NSDate具有有关日期和时间的信息您需要1.从字符串创建NSDate。2.从有关时间的当前日期信息中删除(将时间设置为00:00:00),并且仅在比较日期之后。我认为这种方式并不容易快捷。
oxigen

如果您只对当天本身感兴趣,则可以创建NSDate,然后使用NSCalendar从中获取NSDateComponents,这时您可以在数值上仅比较您感兴趣的值。您还可以获取数量为自时代以来的天数,可用于一次比较。
Jim Dovey 2009年

1
您不应该通过对NSDate描述进行子字符串比较来进行比较,因为Apple可以更改格式,然后这将不再起作用。我之所以这样说,是因为相同的原因导致我的应用在新的OS更新上开始崩溃。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.