I have some NSDate
s that I want to present in terms of weeks, like what Instagram does with their photos timestamp. Values would be "This week", "Last week", "2 weeks ago", and so on to "N weeks ago".
Please help me figure out this algorithm.
Any date arithmetic you need to do in Cocoa (Touch) will involve NSCalendar
and NSDateComponents
. They can figure out for you how the differences between two dates quite easily.
NSDate * originDate = ...;
NSCalendar * cal = [NSCalendar currentCalendar];
NSDateComponents * weekComp = [cal components:NSCalendarUnitWeekOfYear
fromDate:originDate
toDate:[NSDate date] // right now
options:0];
Now [weekComp weekOfYear]
will tell you how many weeks are in between those two dates.
From there, it's just some string formatting:
NSInteger weeksAgo = [weekComp weekOfYear];
NSString * timestampString;
switch( weeksAgo ){
case 0:
timestampString = @"This week";
break;
case 1:
timestampString = @"Last week";
break;
default:
timestampString = [NSString stringWithFormat:@"%d weeks ago", (int)weeksAgo];
}
If you need to count by "calendar" weeks (Sunday through Saturday), so that on Wednesday the previous Saturday is "last week", you'll have to take into account the weekdays of the dates.
NSDateComponents * weekdayComp = [cal components:NSCalendarUnitWeekday|NSCalendarUnitWeekOfYear
fromDate:originDate
toDate:objDate
options:0];
NSInteger weekdaysAgo = [weekdayComp weekday];
NSInteger objWeekday = [cal component:NSCalendarUnitWeekday fromDate:objDate];
Asking the calendar for these two deltas -- weekday and week of year -- in the same call will result in e.g., "1 week, 2 days" for the interval Mon, Jul 13, 2015 to Wed, Jul 22, 2015; the larger unit will be calculated first, and the smaller will be filled with the remainder.
Then you get the weekday number (Sunday=1, Monday=2, etc.) for the target date. If the weekdaysAgo
value is equal or greater, the origin date is in the week previous to that indicated by the weakOfYear
value. Floored division will give the number of weeks to add (either 1 or 0).
NSInteger weeksAgo = [weekdayComp weekOfYear] + (weekdaysAgo / objWeekday);
Then, use this new weeksAgo
value with the same switch
from above.