3

how can I get relative dates in Objective-C?

If I have "today", how do I find "yesterday", "last week", "last two weeks", "one month ago", "two months ago"?

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
Ali
  • 1,975
  • 5
  • 36
  • 55

1 Answers1

10

So if you have an NSDate *today = [NSDate date];, then you can use NSDateComponents to get relative dates.

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *today = [NSDate date];

NSDateComponents *yesterdayComponents = [[NSDateComponents alloc] init];
[yesterdayComponents setDay:-1];
NSDate *yesterday = [calendar dateByAddingComponents:yesterdayComponents toDate:today options:0];
[yesterdayComponents release];

NSDateComponents *twoWeeksAgoComponents = [[NSDateComponents alloc] init];
[twoWeeksAgoComponents setWeek:-2];
NSDate *twoWeeksAgo = [calendar dateByAddingComponents:twoWeeksAgoComponents toDate:today options:0];
[twoWeeksAgoComponents release];

Etc.

NSDateComponents and NSCalendar handle underflowing and overflowing automatically (unless you turn it off with the options: bit). So if today is "28 February" and you want "tomorrow", it will automatically choose either "29 February" or "1 March" depending on the year. It's pretty cool. This is also the only proper way of doing date manipulation.

esilver
  • 27,713
  • 23
  • 122
  • 168
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • the weeks not return corrrectly NSDateComponents *TwoWeeksAgoComponents = [components copy]; [TwoWeeksAgoComponents setWeek:[TwoWeeksAgoComponents week]-2]; NSDate *TwoWeeksAgo = [calendar dateFromComponents:TwoWeeksAgoComponents]; NSLog( [formatter stringFromDate:TwoWeeksAgo] ); [TwoWeeksAgoComponents release]; – Ali Mar 22 '11 at 08:21
  • also does NSCalendar depend on the ipad calender , or it's always georgean – Ali Mar 22 '11 at 08:56
  • This code does not work; it always returns the initial date. I had to use `dateByAddingComponents:toDate:options:`. I'm assuming all the upvotes on this answer are from people who didn't actually test the code. – titaniumdecoy Sep 27 '12 at 21:14
  • @titaniumdecoy I've updated the code. It should work fine now. – Dave DeLong Sep 28 '12 at 02:13
  • @DaveDeLong Thanks. I deleted my answer since it now duplicates yours. – titaniumdecoy Sep 30 '12 at 05:02