9

How do I subtract 100 years from NSDate now?

I have this:

NSDate *now = [NSDate date];
NSDate *hundredYearsAgo = [now dateByAddingTimeInterval:100*365*24*60*60];

But this does not take into account that there are years with 365 days and years with 366 days.

mrd
  • 4,561
  • 10
  • 54
  • 92

2 Answers2

27

Use NSCalendar and NSDateComponents for date calculations.

unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay;
NSDate *now = [NSDate date];
NSCalendar *gregorian = [NSCalendar currentCalendar];
NSDateComponents *comps = [gregorian components:unitFlags fromDate:now];
[comps setYear:[comps year] - 100];
NSDate *hundredYearsAgo = [gregorian dateFromComponents:comps];

Then watch this video, explaining why you should never do date calculations yourself:
The Problem with Time & Timezones - Computerphile

Christian David
  • 1,544
  • 1
  • 18
  • 20
DrummerB
  • 39,814
  • 12
  • 105
  • 142
  • 1
    Is it just me or @DavidRönnqvist's answer is more accurate? You are stripping time out of components resulting a huge offset from date. – Desdenova Jan 24 '14 at 15:19
24

You should really use NSCalendar and NSDateComponents for calculations like that since they can get very tricky and can be full of annoying edge cases.

If you use NSCalendar and NSDateComponents (like the code below) it will take care of all the things like leap years for you.

NSDate *now = [NSDate date];
NSDateComponents *minusHundredYears = [NSDateComponents new];
minusHundredYears.year = -100;
NSDate *hundredYearsAgo = [[NSCalendar currentCalendar] dateByAddingComponents:minusHundredYears
                                                                        toDate:now
                                                                       options:0];

I've written about working with dates in Objective-C general if you want some extra reading on the subject.

David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205