10

I have one query regarding NSDate. I have a date i.e. "2011-10-04 07:36:38 +0000", and I want to check if this date is yesterday, or today or a future date.

How would I go about this?

Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
milanjansari
  • 1,529
  • 2
  • 21
  • 33

4 Answers4

44

Try this:

Note: Change the date format as per your need.

NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"MM/dd/yyyy"];
NSDate* enteredDate = [df dateFromString:@"10/04/2011"];
NSDate * today = [NSDate date];
NSComparisonResult result = [today compare:enteredDate];
switch (result)
{
    case NSOrderedAscending: 
        NSLog(@"Future Date");
                    break;
    case NSOrderedDescending: 
        NSLog(@"Earlier Date");
                    break;
    case NSOrderedSame: 
        NSLog(@"Today/Null Date Passed"); //Not sure why This is case when null/wrong date is passed
                    break;
}
Ludovic Landry
  • 11,606
  • 10
  • 48
  • 80
Shri
  • 2,129
  • 2
  • 22
  • 32
  • 5
    there should be a break after each case statement so as not to enter in the other cases. – Lie-An Sep 13 '13 at 08:38
  • Note that this will never return "today" - NSDate represents a specific instant in time, so `NSOrderedSame` will (essentially) never happen – Tim Jun 08 '17 at 19:23
  • Is there a Swift way of doing this? – Frak Jul 10 '19 at 00:07
6

See Apple's documentation on date calculations:

NSDate *startDate = ...;
NSDate *endDate = ...;

NSCalendar *gregorian = [[NSCalendar alloc]
                 initWithCalendarIdentifier:NSGregorianCalendar];

NSUInteger unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;

NSDateComponents *components = [gregorian components:unitFlags
                                          fromDate:startDate
                                          toDate:endDate options:0];
NSInteger months = [components month];
NSInteger days = [components day];

If days is between +1 and -1 then your date is a candidate for being "today". Obviously you'll need to think about how you handle hours. Presumably the easiest thing would be to set all dates to be 00:00.00 hours on the day in question (truncate the date using an approach like this), and then use those values for the calculation. That way you'd get 0 for today, -1 for yesterday, +1 for tomorrow, and any other value would likewise tell you how far things were in the future or the past.

Community
  • 1
  • 1
Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
  • This will work, but to avoid errors around daylight savings time changes, setting the hours to noon (12:00:00) is much safer. – Suz Oct 12 '11 at 09:31
  • Ironically, I original suggested setting the hours to noon, but the example for truncating had it setting to midnight and I figured might as well keep it consistent! However, if both dates are in the same timezone, then this will make no difference, since daylight savings changes take place at 2am, setting clocks back to 1am, so in all cases two dates from the same timezone will truncate to the same calendar dates, regardless of daylight savings. – Duncan Babbage Oct 12 '11 at 20:09
  • If you are actually wanting to take in account timezones, the best approach would be to transform both dates into the same timezone before doing anything else. – Duncan Babbage Oct 12 '11 at 20:09
  • Time zones and daylight savings are incredibly political (think Venezuela or Israel/Palestine) and I don't think that you can make any real claim that they _all_ change at one time. Some places still apparently use midnight. And even nearby countries can't agree on a date. I've missed more than one train this way. – Suz Oct 12 '11 at 20:21
  • I am using the word "timezone" too loosely; I meant people within the same timezone-daylight savings region. If your app is dealing with more local concerns (two dates that relate to me personally somehow... i.e. when I did this thing vs. now) then many of these issues may disappear. :) – Duncan Babbage Oct 13 '11 at 08:16
  • Incidentally, as someone who lives in a timezone that sometimes goes to GMT +13:00, setting both dates to midday _won't_ necessarily work either! :) – Duncan Babbage Oct 13 '11 at 08:18
2

Use any of the folowing according to ur need,

– earlierDate:
– laterDate:
– compare:

Refer this http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html

EXC_BAD_ACCESS
  • 2,699
  • 2
  • 21
  • 25
  • 1
    This is not available for iOS development. From the site, it is clearly say so: "Availability Available in OS X v10.0 and later." – JHHoang Nov 29 '12 at 15:57
1
-(NSString*)timeAgoFor:(NSString*)tipping_date
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    NSDate *date = [dateFormatter dateFromString:tipping_date];
    NSString *key = @"";
    NSTimeInterval ti = [date timeIntervalSinceDate:[NSDate date]];
    key = (ti > 0) ? @"Left" : @"Ago";

    ti = ABS(ti);
    NSDate * today = [NSDate date];
    NSComparisonResult result = [today compare:date];

    if (result == NSOrderedSame) {
        return[NSString stringWithFormat:@"Today"];
    }
    else if (ti < 86400 * 2) {
        return[NSString stringWithFormat:@"1 Day %@",key];
    }else if (ti < 86400 * 7) {
        int diff = round(ti / 60 / 60 / 24);
        return[NSString stringWithFormat:@"%d Days %@", diff,key];
    }else {
        int diff = round(ti / (86400 * 7));
        return[NSString stringWithFormat:@"%d Wks %@", diff,key];
    }
}
Atef
  • 2,872
  • 1
  • 36
  • 32
  • I used this but somehow Today never came, so I had to modify it so that i compares only the date. Rest works fine. Finally got the issue it was comparing the time with it. I had to adjust accordingly – ChArAnJiT Dec 08 '15 at 18:22