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

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

110462 次浏览

What you really need is to compare two objects of the same kind.

  1. Create an NSDate out of your string date (@"2009-05-11") :
    http://blog.evandavey.com/2008/12/how-to-convert-a-string-to-nsdate.html

  2. If the current date is a string too, make it an NSDate. If its already an NSDate, leave it.

..

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

If you make both dates NSDates you can use NSDate's compare: method:

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");

You can take a look at the docs here.

Cocoa has couple of methods for this:

in NSDate

– isEqualToDate:
– earlierDate:
– laterDate:
– compare:

When you use - (NSComparisonResult)compare:(NSDate *)anotherDate ,you get back one of these:

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.

example:

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];

Here buddy. This function will match your date with any specific date and will be able to tell whether they match or not. You can also modify the components to match your requirements.

- (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];}

Regards, Naveed Butt

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");

There are other ways that you may use to compare an NSDate objects. Each of the methods will be more efficient at certain tasks. I have chosen the compare method because it will handle most of your basic date comparison needs.

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;


}

Enjoy coding......

The best way I found was to check the difference between the given date and today:

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

According to Listing 13 of Calendrical Calculations in Apple's Date and Time Programming Guide [NSCalendar ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:myDate] gives you the number of midnights since the start of the era. This way it's easy to check whether the date is yesterday, today, or tomorrow.

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;
}
}

This category offers a neat way to compare NSDates:

#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

And the implementation:

#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

Simple to use:

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

By this method also you can compare two dates

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


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


}

Here's the Swift variant on Pascal's answer:

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)
}
}

Which can be used as:

self.expireDate.isEarlierThanOrEqualTo(NSDate())

Here's the function from Naveed Rafi's answer converted to Swift if anyone else is looking for it:

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)
}
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];

Then use NSComparisonResult to compare date.