1

I am trying to calculate whether any of my Address Book's contacts have a birthday in the next 10 days. There's plenty of code on line to compare dates, but I only want to compare day and month. For example, if a contact was born 05/01/1960 (and assuming today is 04/24/2011), then I only want to calculate that there are only six days till their birthday. Help appreciated.

Jeremy
  • 883
  • 1
  • 20
  • 41

3 Answers3

4

Change the birthday to this year (or next year if the birthday was already in this year) and calculate with NSDateComponents and NSCalendar.

Looks a bit complicated, but you could do it like this:

NSDate *birthDay = ... // [calendar dateFromComponents:myBirthDay];

NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];

NSDateComponents *thisYearComponents = [calendar components:NSYearCalendarUnit fromDate:[NSDate date]];
NSDateComponents *birthDayComponents = [calendar components:NSMonthCalendarUnit|NSDayCalendarUnit fromDate:birthDay];
[birthDayComponents setYear:[thisYearComponents year]];

NSDate *birthDayThisYear = [calendar dateFromComponents:birthDayComponents];

NSDateComponents *difference = [calendar components:NSDayCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
if ([difference day] < 0) {
    // this years birthday is already over. calculate distance to next years birthday
    [birthDayComponents setYear:[thisYearComponents year]+1];
    birthDayThisYear = [calendar dateFromComponents:birthDayComponents];
    difference = [calendar components:NSDayCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
}


NSLog(@"%i days until birthday", [difference day]);
Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
  • Fantastic! Thanks fluchtpunkt. This works perfectly. Who would have thought something so simple needed this amount of work. – Jeremy Apr 24 '11 at 18:39
  • Everything that is date related needs a huge amount of code if you want to do it right. That's why there are so many bugs with timezones, daylight saving, leap years and so on. (Yes I look at you 86400 users.) We can feel happy that we have NSDateComponents and NSCalendar, otherwise you probably would need 20 times more code. – Matthias Bauch Apr 24 '11 at 18:47
  • Oh and btw, don't remove the `if ([difference day] < 0)` part, even if you think you are not interested in next years birthdays. Actually you are interested, at least for the last 10 days of a year for birthdays that happen in the first 10 days of a year. Took me a while to figure that one out. – Matthias Bauch Apr 24 '11 at 18:50
0

Once you have retrieved your contact's birthdate:

ABAddressBook get birthday property

you need to adjust the year component:

NSDate - Changing the year value

Then, you can compute the number of days till her birthday:

NSDate countdown in days

Community
  • 1
  • 1
magma
  • 8,432
  • 1
  • 35
  • 33
0

Use the below NSDate function with your contact NSDate.

- (NSTimeInterval)timeIntervalSinceNow

The above function returns the interval between the receiver and the current date and time.

   NSTimeInterval interval = [date1 timeIntervalSinceNow:myContactDate];

NSTimeInterval is the elapsed time in seconds (expressed as a floating point number). You could then divide by 86400, which is the number of seconds in a day and round to the nearest integer.

NSInteger days = interval / 86400;

Now you have number of days...

EDITED:

You could also use the NSCalendar and NSDateComponents to only get the day component between two date.

- (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts

Use the below code as reference. (Taken From Apple Documentation for NSCalendar)

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDate *startDate = ...;
    NSDate *endDate = ...;
    unsigned int unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;

    NSDateComponents *comps = [gregorian components:unitFlags fromDate:startDate  toDate:endDate  options:0];
    int months = [comps month];
    int days = [comps day];
Jhaliya - Praveen Sharma
  • 31,697
  • 9
  • 72
  • 76