开发者

Compare NSDate for Today or Yesterday

开发者 https://www.devze.com 2022-12-31 14:35 出处:网络
Well I guess this has been asked a thousand times, but for some reason the answeres dont really work or had other problems,....

Well I guess this has been asked a thousand times, but for some reason the answeres dont really work or had other problems,....

Anyway here is what I have "working" :

    NSCalendar *calendar = [NSCalendar currentCalendar];    
    NSDate *currentDate = [NSDate date];
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    // set tomorrow (0: today, -1: yesterday)
    [comps setDay:0];
    NSDate *dateToday = [calendar dateByAddingComponents:comps toDate:currentDate options:0];
    [comps setDay:-1];
    NSDate *dateYesterday = [calendar dateByAddingComponents:comps toDate:currentDate options:0];
    [comps release];


NSString *todayString = [self.dateFormatter stringFromDate:dateToday] ;
NSString *yesterdayString = [self.dateFormatter stringFromDate:dateYesterday] ;
NSString *refDateString = [self.dateFormatter stringFromDate:info.date];

if ([refDateString isEqualToString:todayString]) 
{
    cell.title.text =  @"Today";
} else if ([refDateString isEqualToString:yesterdayString]) 
{
    cell.title.text =  @"Yesterday";
} else 
{
    cell.title.text =  [self.dateFormatter stringFromDate:info.date];
}

Now to the problem(s) :

That seems to be an awefull lot of code for just a date comparinson, is there an easier way ?

And the most important question is the release of all the objects. As might have guessed, I use this in a UITableViewController. I also have these lines in my code :

//[calendar release];
//[currentDate release];
//[dateToday release];
//[dateYesterday release];
//[todayString release];
//[yesterdayString release];
//[refDateString release];

The problem is that as soon that I uncomment one of these lines, my app crashes an开发者_如何学JAVAd I have no idea why ?! I hope someone can enlighten me here.

Thanks lot.


The easiest way to do it is to just compare the description of the dates:

// Your dates:
NSDate * today = [NSDate date];
NSDate * yesterday = [NSDate dateWithTimeIntervalSinceNow:-86400]; //86400 is the seconds in a day
NSDate * refDate; // your reference date

// 10 first characters of description is the calendar date:
NSString * todayString = [[today description] substringToIndex:10];
NSString * yesterdayString = [[yesterday description] substringToIndex:10];
NSString * refDateString = [[refDate description] substringToIndex:10];

if ([refDateString isEqualToString:todayString]) 
{
    cell.title.text =  @"Today";
} else if ([refDateString isEqualToString:yesterdayString]) 
{
    cell.title.text =  @"Yesterday";
} else 
{
    cell.title.text =  refDateString;
}

If you want to change the format of the date string you could use descriptionWithLocale: instead.


I know this is an old question, but I was just doing something similar myself and came upon it.

First of all, since iOS 4.0 (and Mac OS 10.6), NSDateFormatter can do relative dates, which gives you "Today" and "Yesterday" automatically.

NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setTimeStyle:NSDateFormatterNoStyle];
[formatter setDateStyle:NSDateFormatterShortStyle];
[formatter setDoesRelativeDateFormatting:YES];

NSString* dateString = [formatter stringFromDate:[NSDate date]];    
NSLog( @"date = %@", dateString );

Which outputs:

2014-03-15 15:26:37.683 TestApp[1293:303] date = Today

However, the OP was asking how to compare an NSDate for today or yesterday, something I also wanted to do, relative date formatting aside. Here's what I came up with, implemented as a category on NSDate:

@implementation NSDate (IsToday)

- (BOOL) isToday
{
    NSCalendar* calendar = [NSCalendar currentCalendar];

    // Components representing the day of our date.
    NSDateComponents* dateComp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
                                             fromDate:self];
    NSDate* date = [calendar dateFromComponents:dateComp];

    // Components representing today.
    NSDateComponents* todayComp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
                                              fromDate:[NSDate date]];
    NSDate* todayDate = [calendar dateFromComponents:todayComp];

    // If the dates are equal, then our date is today.
    return [date isEqualToDate:todayDate];
}

@end

The reason I wanted to do this is so that I could display the time of things created today, and the date of things not created today - similar to how Mail.app shows the dates on messages. It looks like this:

- (NSString*) postDateToString:(NSDate*)aDate
{
    static NSDateFormatter* todayFormatter = nil;
    if( todayFormatter == nil ) {
        todayFormatter = [[NSDateFormatter alloc] init];
        [todayFormatter setTimeStyle:NSDateFormatterShortStyle];
        [todayFormatter setDateStyle:NSDateFormatterNoStyle];
    }

    static NSDateFormatter* notTodayFormatter = nil;
    if( notTodayFormatter == nil ) {
        notTodayFormatter = [[NSDateFormatter alloc] init];
        [notTodayFormatter setTimeStyle:NSDateFormatterNoStyle];
        [notTodayFormatter setDateStyle:NSDateFormatterShortStyle];
        [notTodayFormatter setDoesRelativeDateFormatting:YES];
    }

    NSDateFormatter* formatter = notTodayFormatter;

    if( [aDate isToday] ) {
        formatter = todayFormatter;
    }

    return [formatter stringFromDate:aDate];
}


I can suggest to use this open source project: https://github.com/erica/NSDate-Extensions

You can check the current methods:

+ (NSDate *) dateTomorrow
+ (NSDate *) dateYesterday


You can compare two NSDate objects using the isEqualToDate method, will return a bool (yes or no) telling you if the dates are equal. See Apple Documentation.

As for the releasing the objects - the rule in objective-c is that you only release objects that you alloc memory for during the course of your method. The only object you're specifically allocating memory for in your code is comps so it's the only one you should release - and you've done so. Releasing memory for objects you never allocated is probably what is causing your app to crash. When the methods which actually allocated those objects attempts to release them or another reference to them tries to access them, they'll trigger an EXC_BAD_ACCESS error as you've already released them!

So don't just comment out those release lines, delete them from your script - there's no need for them!

0

精彩评论

暂无评论...
验证码 换一张
取 消