Ad

Our DNA is written in Swift
Jump

Add one Week and Skip Weekend

dbarret asks:

“I need some help with this issue and I’m hoping you have the time to point me in the right direction, here goes:

  1. I want to display today’s date in a UILabel, then with a button event, the tricky part…
  2. display a date 7 days in the future UNLESS it’s the weekend, then it will display the following Monday.

So basically I want to display ONLY weekdays, no weekends… it that even possible?”

Of course it is possible. In this case it’s not even very difficult.

I assume that you know how to display a UILabel and set its text. So in this article I’ll show how to enhance what we previously learned about adding days to NSDates and add extra code to also skip weekend days.

To get the current date and display it in a properly localized fashion you do this:

// create a date object with the current time
NSDate *today = [NSDate date];
 
// create and configure a date formatter
NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
[df setDateStyle:NSDateFormatterMediumStyle];
 
// make formatted string
NSString *todayString = [df stringFromDate:today];
NSLog(@"%@", todayString);

The advantage of using an NSDateFormatter is that it comes with 3 default formats each for the date and time which get set with setDateStyle and setTimeStyle accordingly. Combinations are also possible. Those are appropriately localized to the currently selected locale of the iPhone so it’s highly recommended using those and not mess with setDateFormat to set any arbitrary format.

NSDateFormatterShortStyle
date: Nov 14, 2009
time: 11:25 AM

NSDateFormatterMediumStyle
date: Nov 14, 2009
time: 11:25:48 AM

NSDateFormatterLongStyle
date: November 14, 2009
time: 11:25:48 AM GMT+01:00

Note that the short and medium style are identical for dates, but not for the time portion. Well, that’s it for question 1.

For the second part, we refer back to the previous Q&A article on how to add days to a date. With a twist, we need to skip days belonging to the weekend.

NSDateComponents is used here in both functions that it is good for, namely for adding days to a date and for retrieving information about an NSDate. In both cases we need to use the help offered by NSCalendar because theoretically there are several different calendars that NSDate could refer to, with different results. Though we’ll stick with the one that was invented by Pope Gregory XIII in 1582.

We’ll package it all into a nice method with a descriptive name to be used later.

- (NSDate *)addWeekToDateAndSkipWeekend:(NSDate *)now
{
	int daysToAdd = 6; // we'll add the 7th later
 
	// set up date components
	NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
	[components setDay:daysToAdd];
 
	// create a calendar
	NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
 
	NSDate *newDate = [gregorian dateByAddingComponents:components toDate:now options:0];
 
	[components setDay:1]; // reuse to skip single days
	NSDateComponents *newDateComps; // new componets to get weekday
 
	// do always executed once, so we add the 7th day here
	do
	{
		// add one day
		newDate = [gregorian dateByAddingComponents:components toDate:newDate options:0];
		newDateComps = [gregorian components:NSWeekdayCalendarUnit fromDate:newDate];
 
		// repeat if the date is Saturday (7) or Sunday (1)
		NSLog(@"weekday: %d", [newDateComps weekday]);
	} while (([newDateComps weekday]==7)||([newDateComps weekday]==1));
 
	return newDate;
}

To test it, all we need is to get the current date, call our function and NSLog the result. You can always use NSLog with the %@ for objects because this is shorthand for calling the objects description method. Which – conveniently – for NSDates outputs a date string.

NSDate *today = [NSDate date];
NSDate *plusOneWeek = [self addWeekToDateAndSkipWeekend:today];
NSLog(@"plus 1 week: %@", plusOneWeek);

That’s all it takes in terms of programming logic. Depending on how often you use this method it might also be a good candidate to put in your helper category collection which every good developer begins to have sooner or later. In my case I would put it into my NSDate+Helpers category and instead of the “now” parameter I would use “self” instead.


Categories: Q&A

0 COmments »

  1. Wow! I never would have figured this out on my own. Thank you so much for your help!