How to compare time - objective-c

How to compare time in Objective C?
if (nowTime > 9:00 PM) && (nowTime < 7:00 AM)
{
doSomething;
}

If you want to get the current hour and compare it to some times, you're going to have to use NSDate, NSDateComponents, and NSCalendar.
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:[NSDate date]];
NSInteger currentHour = [components hour];
NSInteger currentMinute = [components minute];
NSInteger currentSecond = [components second];
if (currentHour < 7 || (currentHour > 21 || currentHour == 21 && (currentMinute > 0 || currentSecond > 0))) {
// Do Something
}
That will check if the time is between 9:00 PM and 7:00 AM. Of course, if you're going to want different times you'll have to change the code a little.
Read about NSDate, NSDateComponents, and NSCalendar to learn more.

Theres a perfect formula for this. Just for future references
Below is the sample code :
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:[NSDate date]];
NSInteger currHr = [components hour];
NSInteger currtMin = [components minute];
NSString *startTime = #"21:00";
NSString *endTime = #"07:00";
int stHr = [[[startTime componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
int stMin = [[[startTime componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
int enHr = [[[endTime componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
int enMin = [[[endTime componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
int formStTime = (stHr*60)+stMin;
int formEnTime = (enHr*60)+enMin;
int nowTime = (int)((currHr*60)+currtMin);
if(nowTime >= formStTime && nowTime <= formEnTime) {
// Do Some Nasty Stuff..
}

NSDate *now = [NSDate date];
if (([now compare:earlierDateVariable] == NSOrderedDescending) && ([now compare:laterDateVariable] == NSOrderedAscending ))
{
// Do something here...
}
To set earlierDate and laterDate, straight from Apple's documentation available here
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:22];
[comps setMonth:03];
[comps setYear:2011];
[comps setHour:21];
[comps setMinute:00];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *earlierDateVariable = [gregorian dateFromComponents:comps];
[comps release];
[gregorian release];
And the same goes for later date...

For checking current time or any time between two times ::
NSCalendar *calendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendarUnit units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;
NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
return [self isDateComponent:components withinStartHour:startH startMin:startM endHour:endH endMin:endM];
-(BOOL)isDateComponent:(NSDateComponents*)components withinStartHour:(int)startH startMin:(int)startM endHour:(int)endH endMin:(int)endM
{
if (endH < startH) {
return ( [self isDateComponent:components betweenStartHour:startH startmin:startM endHour:23 endMin:59] ||
[self isDateComponent:components betweenStartHour:0 startmin:0 endHour:endH endMin:endM] );
}
else {
return [self isDateComponent:components betweenStartHour:startH startmin:startM endHour:endH endMin:endM];
}
}
-(BOOL)isDateComponent:(NSDateComponents*)components betweenStartHour:(int)startH startmin:(int)startM endHour:(int)endH endMin:(int)endM
{
int currentH = components.hour;
int currentM = components.minute ;
DDLogVerbose(#"start : %i-%i, end : %i-%i, current:%i-%i",startH,startM,endH,endM,currentH,currentM);
startM = startM + startH * 60;
endM = endM + endH * 60;
currentM = components.minute + currentH*60;
if ( startM <= currentM && currentM < endM ) {
return YES;
}
else {
return NO;
}
}

I used the Answer Given above by rye. I just had to convert my 7:00 AM and 9:00 PM to 24 hours. Here's the method I used
/**
Willl return YES if the Restaurant is OPEN at the Moment else NO
*/
-(BOOL) isShopOpen:(NSString *) startTime closeTime:(NSString *) endTime{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:[NSDate date]];
NSInteger currHr = [components hour];
NSInteger currtMin = [components minute];
int stHr ;
int stMin ;
int enHr ;
int enMin ;
if([startTime containsString:#"PM"]){
startTime = [startTime stringByReplacingOccurrencesOfString:#" PM" withString:#""];
stHr=[[[startTime componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
stHr=stHr+12;
stMin = [[[startTime componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
}else{
startTime = [startTime stringByReplacingOccurrencesOfString:#" AM" withString:#""];
stHr=[[[startTime componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
stMin = [[[startTime componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
}
if([endTime containsString:#"PM"]){
endTime = [endTime stringByReplacingOccurrencesOfString:#" PM" withString:#""];
enHr=[[[endTime componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
enHr=enHr+12;
enMin = [[[startTime componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
}else{
endTime = [endTime stringByReplacingOccurrencesOfString:#" AM" withString:#""];
enHr=[[[endTime componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
enMin = [[[startTime componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
}
int formStTime = (stHr*60)+stMin;
int formEnTime = (enHr*60)+enMin;
int nowTime = (currHr*60)+currtMin;
if(nowTime >= formStTime && nowTime <= formEnTime) {
// Do Some Nasty Stuff..
return YES;
}else{
return NO;
}
}

If anybody needs, this is a code to create sections in a tableView according to the date of objects.
Method to get dates for today, yesterday, etc. (taken from ReMail project DateUtil class):
#define DATE_UTIL_SECS_PER_DAY 86400
-(void)refreshData {
//TODO(gabor): Call this every hour or so to refresh what today, yesterday, etc. mean
NSCalendar *gregorian = [NSCalendar currentCalendar];
self.today = [NSDate date];
self.yesterday = [today dateByAddingTimeInterval:-DATE_UTIL_SECS_PER_DAY];
self.lastWeek = [today dateByAddingTimeInterval:-6*DATE_UTIL_SECS_PER_DAY];
self.todayComponents = [gregorian components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:today];
self.yesterdayComponents = [gregorian components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:yesterday];
self.dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
}
Method to sort tableData for table view sections according to date:
// Sort tableData objects according to the date
for (MCMessage *mcMessage in self.tableData) {
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:mcMessage.dateTime];
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
NSLog(#"Day:%d, Month:%d, Year:%d. Today day:%d. Yesterday:%d", day, month, year, dateUtil.todayComponents.day, dateUtil.yesterdayComponents.day);
if ((dateUtil.todayComponents.day == day) && (dateUtil.todayComponents.month == month) && (dateUtil.todayComponents.year == year))
{
[self.todayData addObject:mcMessage];
}
else if ((dateUtil.yesterdayComponents.day == day) && (dateUtil.yesterdayComponents.month == month) && (dateUtil.yesterdayComponents.year == year))
{
[self.yesterdayData addObject:mcMessage];
}
else
{
[self.soonerData addObject:mcMessage];
}
}

Related

Cocoa - Calculate working days between two dates

I new in cocoa programing and I want to know how I get the number of working days between to dates. So only from Monday to Friday. Thanks.
NSDate *startDate = ...;
NSDate *stopDate = ...;
NSDateFormatter *df = [NSDateFormatter new];
df.dateFormat = #"yyyy-MM-dd";
startDate = [df dateFromString:[df stringFromDate:startDate]]; // get start of the day
NSDateComponents *comps = [NSDateComponents new];
comps.day = 1; // one day in NSDateComponents
NSUInteger count = 0;
while ([stopDate timeIntervalSinceDate:startDate] >= 0) {
NSInteger weekday = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:startDate].weekday;
if (weekday != 1 && weekday != 6) ++count; // filter out weekend days - 6 and 1
startDate = [[NSCalendar currentCalendar] dateByAddingComponents:comps toDate:startDate options:0]; // increment start day
}

24 hours divided by 30 minutes apart - NSDate

I'm trying to get an NSMutableArray of NSDates each NSDate object targets the nearest rounded either HH:00 or HH:30 for the next 24 hours from now.
lets say right now its 02:31 I want an output of #[03:00,03:30,04:00,04:30...03:00(of the next day)]
if its 02:29 then I want #[02:30,03:00 and so on till the next day at 02:30].
right now I have the code below and it works almost all the time, yet rarely I get an output of all the NSDate objects that I want with a remainder of an extra minute(#[03:01,03:31:04:01...so on]).
any ideas ?
-(NSMutableArray*)TwentyFourHoursFromNowDivicedBy30Mins
{
NSMutableArray * dateArray = [NSMutableArray array];
NSCalendar * cal = [NSCalendar currentCalendar];
NSDateComponents * plusDays = [NSDateComponents new];
NSDate * now = [self changeTimeValue:[NSDate date]];
for( NSUInteger day = 0; day < 2; day++ )
{
[plusDays setDay:day];
[dateArray addObject:[cal dateByAddingComponents:plusDays toDate:now options:0]];
}
NSDate *startDate = [dateArray objectAtIndex:0];
NSDate *endDate = [dateArray objectAtIndex:1];
NSDateComponents *diff = [[NSDateComponents alloc] init];
[diff setMinute:0];
NSCalendar *calz = [NSCalendar currentCalendar];
NSDate *tmp = startDate;
NSMutableArray *dates = [NSMutableArray arrayWithObject:tmp];
while ([tmp laterDate:endDate] == endDate) {
[diff setMinute:[diff minute] + 30];
tmp = [calz dateByAddingComponents:diff toDate:startDate options:0];
[dates addObject:tmp];
}
return dates;
}
- (NSDate *)changeTimeValue:(NSDate *)dateValue{
NSDateComponents *time = [[NSCalendar currentCalendar]
components:NSHourCalendarUnit | NSMinuteCalendarUnit
fromDate:dateValue];
long val = 0;
NSDate *newDate = [[NSDate alloc] init];
NSInteger minutes = [time minute];
if(minutes > 0 && minutes < 30) {
val = 30 - minutes; NSTimeInterval aTimeInterval = [dateValue
timeIntervalSinceReferenceDate] + 60 * val + minutes;
newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
return newDate;
} else if(minutes > 30 && minutes < 60) {
val = 60 - minutes;
NSTimeInterval aTimeInterval = [dateValue timeIntervalSinceReferenceDate]
+ 60 * val;
newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
return newDate;
} else {
return newDate;
}
}
You're not zeroing out the seconds in your changeTimeValue, and in any case I think you've overcomplicated it. So I suspect you're subsequently seeing rounding issues. Just use NSDateComponents to do the whole job:
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponents = [currentCalendar
components:NSHourCalendarUnit |
NSMinuteCalendarUnit |
NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit
fromDate:dateValue];
dateComponents.minute += 15;
dateComponents.minute -= dateComponents.minute%30;
return [currentCalendar dateFromComponents:dateComponents];

How would I add only business days to an NSDate?

I have an issue related to calculating business days in Objective-C.
I need to add X business days to a given NSDate.
For example, if I have a date: Friday 22-Oct-2010, and I add 2 business days, I should get: Tuesday 26-Oct-2010.
Thanks in advance.
There are two parts to this:
Weekends
Holidays
I'm going to pull from two other posts to help me out.
For weekends, I'm going to need to know a given date's day of the week. For that, this post comes in handy:
How to check what day of the week it is (i.e. Tues, Fri?) and compare two NSDates?
For holidays, #vikingosegundo has a pretty great suggestion on this post:
List of all American holidays as NSDates
First, let's deal with the weekends;
I've wrapped up the suggestion in the post I cited above into this nice little helper function which tells us if a date is a weekday:
BOOL isWeekday(NSDate * date)
{
int day = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:date] weekday];
const int kSunday = 1;
const int kSaturday = 7;
BOOL isWeekdayResult = day != kSunday && day != kSaturday;
return isWeekdayResult;
}
We'll need a way to increment a date by a given number of days:
NSDate * addDaysToDate(NSDate * date, int days)
{
NSDateComponents * components = [[NSDateComponents alloc] init];
[components setDay:days];
NSDate * result = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:date options:0];
[components release];
return result;
}
We need a way to skip over weekends:
NSDate * ensureDateIsWeekday(NSDate * date)
{
while (!isWeekday(date))
{
// Add one day to the date:
date = addDaysToDate(date, 1);
}
return date;
}
And we need a way to add an arbitrary number of days to a date:
NSDate * addBusinessDaysToDate(NSDate * start, int daysToAdvance)
{
NSDate * end = start;
for (int i = 0; i < daysToAdvance; i++)
{
// If the current date is a weekend, advance:
end = ensureDateIsWeekday(end);
// And move the date forward by one day:
end = addDaysToDate(end, 1);
}
// Finally, make sure we didn't end on a weekend:
end = ensureDateIsWeekday(end);
return end;
}
Note; There is an obvious optimization I skipped - you could easily add more than one day at a time to the current date - but the point of my post is to show you how to do this yourself - and not necessarily to come up with the best possible solution.
Now lets tie that up and see what we have so far:
int main() {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSDate * start = [NSDate date];
int daysToAdvance = 10;
NSDate * end = addBusinessDaysToDate(start, daysToAdvance);
NSLog(#"Result: %#", [end descriptionWithCalendarFormat:#"%Y-%m-%d"
timeZone:nil
locale:nil]);
[pool drain];
return 0;
}
So, we've got weekends covered, now we need to pull in the holidays.
Pulling in some RSS feed, or data from another source is definitely beyond the scope of my post... so, let's just assume you have some dates you know are holidays, or, according to your work calendar, are days off.
Now, I'm going to do this with an NSArray... but, again, this leaves plenty of room for improvement - at minimum it should be sorted. Better yet, some sort of hash set for fast lookups of dates. But, this example should suffice to explain the concept. (Here we construct an array which indicates there are holidays two and three days from now)
NSMutableArray * holidays = [[NSMutableArray alloc] init];
[holidays addObject:addDaysToDate(start, 2)];
[holidays addObject:addDaysToDate(start, 3)];
And, the implementation for this will be very similar to the weekends. We'll make sure the day isn't a holiday. If it is, we'll advance to the next day. So, a collection of methods to help with that:
BOOL isHoliday(NSDate * date, NSArray * holidays)
{
BOOL isHolidayResult = NO;
const unsigned kUnits = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents * components = [[NSCalendar currentCalendar] components:kUnits fromDate:date];
for (int i = 0; i < [holidays count]; i++)
{
NSDate * holiday = [holidays objectAtIndex:i];
NSDateComponents * holidayDateComponents = [[NSCalendar currentCalendar] components:kUnits fromDate:holiday];
if ([components year] == [holidayDateComponents year]
&& [components month] == [holidayDateComponents month]
&& [components day] == [holidayDateComponents day])
{
isHolidayResult = YES;
break;
}
}
return isHolidayResult;
}
and:
NSDate * ensureDateIsntHoliday(NSDate * date, NSArray * holidays)
{
while (isHoliday(date, holidays))
{
// Add one day to the date:
date = addDaysToDate(date, 1);
}
return date;
}
And, finally, make some modifications to our addition function to take into account the holidays:
NSDate * addBusinessDaysToDate(NSDate * start, int daysToAdvance, NSArray * holidays)
{
NSDate * end = start;
for (int i = 0; i < daysToAdvance; i++)
{
// If the current date is a weekend, advance:
end = ensureDateIsWeekday(end);
// If the current date is a holiday, advance:
end = ensureDateIsntHoliday(end, holidays);
// And move the date forward by one day:
end = addDaysToDate(end, 1);
}
// Finally, make sure we didn't end on a weekend or a holiday:
end = ensureDateIsWeekday(end);
end = ensureDateIsntHoliday(end, holidays);
return end;
}
Go ahead and try it:
int main() {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSDate * start = [NSDate date];
int daysToAdvance = 10;
NSMutableArray * holidays = [[NSMutableArray alloc] init];
[holidays addObject:addDaysToDate(start, 2)];
[holidays addObject:addDaysToDate(start, 3)];
NSDate * end = addBusinessDaysToDate(start, daysToAdvance, holidays);
[holidays release];
NSLog(#"Result: %#", [end descriptionWithCalendarFormat:#"%Y-%m-%d"
timeZone:nil
locale:nil]);
[pool drain];
return 0;
}
If you want the whole project, here ya go: http://snipt.org/xolnl
There's nothing built into NSDate or NSCalendar that counts business days for you. Business days depend to some degree on the business in question. In the US, "business day" generally means weekdays that aren't holidays, but each company determines which holidays to observe and when. For example, some businesses move observance of minor holidays to the last week of the year so that employees can be off between Christmas and New Year's Day without taking vacation.
So, you'll need to decide exactly what you mean by business day. It should then be simple enough write a little method to calculate a future date by adding some number of business days. Then use a category to add a method like -dateByAddingBusinessDays: to NSDate.
this answer is late to the party but…. I thought i might improve on above answers to determine business days by working with NSDateComponents directly of your date in a nice loop.
#define CURRENTC [NSCalendar currentCalendar]
#define CURRENTD [NSDate date]
NSInteger theWeekday;
NSDateComponents* temporalComponents = [[NSDateComponents alloc] init];
[temporalComponents setCalendar:CURRENTC];
[temporalComponents setDay: 13];
[temporalComponents setMonth: 2];
[temporalComponents setYear: theYear];
// CURRENTC =the current calendar which determines things like how
// many days in week for local, also the critical “what is a weekend”
// you can also convert a date directly to components. but the critical thing is
// to get the CURRENTC in, either way.
case 3:{ // the case of finding business days
NSDateComponents* startComp = [temporalComponents copy]; // start date components
for (int i = 1; i <= offset; i++) //offset is the number of busi days you want.
{
do {
[temporalComponents setDay: [temporalComponents day] + 1];
NSDate* tempDate = [CURRENTC dateFromComponents:temporalComponents];
theWeekday = [[CURRENTC components:NSWeekdayCalendarUnit fromDate:tempDate] weekday];
} while ((theWeekday == 1) || (theWeekday == 7));
}
[self findHolidaysStart:startComp end:temporalComponents]; // much more involved routine.
[startComp release];
break;
}
// use startComp and temporalcomponents before releasing
// temporalComponents now contain an offset of the real number of days
// needed to offset for busi days. startComp is just your starting date….(in components)
// theWeekday is an integer between 1 for sunday, and 7 for saturday, (also determined
// by CURRENTC
turning this back into NSDate, and you are done. Holidays are much more involved.. but can actually be calculated if just using federal holidays and a few others. because they are always something like “3rd monday of January”
here is what the findHolidaysStart:startComp end: starts out like, you can imagine the rest.
// imported
[holidayArray addObject:[CURRENTC dateFromComponents:startComp]];
[holidayArray addObject:[CURRENTC dateFromComponents:endComp]];
// hardcoded
dateComponents = [[NSDateComponents alloc] init];
[dateComponents setCalendar:CURRENTC];
[dateComponents setDay: 1];
[dateComponents setMonth: 1];
[dateComponents setYear: theYear];
theWeekday = [[CURRENTC components:NSWeekdayCalendarUnit fromDate:[CURRENTC dateFromComponents:dateComponents]] weekday];
if (theWeekday == 1) [dateComponents setDay:2];
if (theWeekday == 7) {[dateComponents setDay:31]; [dateComponents setYear: theYear-1];}
[holidayArray addObject:[CURRENTC dateFromComponents:dateComponents]];
[dateComponents release];
I took #steve's answer and added a method to calculate the days of all the federal holidays in USA and put it all in a Category. I've tested it and it works nicely. Check it out.
#import "NSDate+BussinessDay.h"
#implementation NSDate (BussinessDay)
-(NSDate *)addBusinessDays:(int)daysToAdvance{
NSDate * end = self;
NSArray *holidays = [self getUSHolidyas];
for (int i = 0; i < daysToAdvance; i++)
{
// Move the date forward by one day:
end = [self addDays:1 toDate:end];
// If the current date is a weekday, advance:
end = [self ensureDateIsWeekday:end];
// If the current date is a holiday, advance:
end = [self ensureDateIsntHoliday:end forHolidays:holidays];
}
return end;
}
#pragma mark - Bussiness Days Calculations
-(BOOL)isWeekday:(NSDate *) date{
int day = (int)[[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:date] weekday];
const int kSunday = 1;
const int kSaturday = 7;
BOOL isWeekdayResult = day != kSunday && day != kSaturday;
return isWeekdayResult;
}
-(NSDate *)addDays:(int)days toDate:(NSDate *)date{
NSDateComponents * components = [[NSDateComponents alloc] init];
[components setDay:days];
NSDate * result = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:date options:0];
return result;
}
-(NSDate *)ensureDateIsWeekday:(NSDate *)date{
while (![self isWeekday:date])
{
// Add one day to the date:
date = [self addDays:1 toDate:date];
}
return date;
}
-(BOOL)isHoliday:(NSDate *)date forHolidays:(NSArray *)holidays{
BOOL isHolidayResult = NO;
const unsigned kUnits = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents * components = [[NSCalendar currentCalendar] components:kUnits fromDate:date];
for (int i = 0; i < [holidays count]; i++)
{
NSDate * holiday = [holidays objectAtIndex:i];
NSDateComponents * holidayDateComponents = [[NSCalendar currentCalendar] components:kUnits fromDate:holiday];
if ([components year] == [holidayDateComponents year]
&& [components month] == [holidayDateComponents month]
&& [components day] == [holidayDateComponents day])
{
isHolidayResult = YES;
break;
}
}
return isHolidayResult;
}
-(NSDate *)ensureDateIsntHoliday:(NSDate *)date forHolidays:(NSArray *)holidays{
while ([self isHoliday:date forHolidays:holidays])
{
// Add one day to the date:
date = [self addDays:1 toDate:date];
}
return date;
}
-(NSArray *)getUSHolidyas{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy";
NSString *year = [formatter stringFromDate:[NSDate date]];
NSString *nextYear = [formatter stringFromDate:[NSDate dateWithTimeIntervalSinceNow:(60*60*24*365)]];
formatter.dateFormat = #"M/d/yyyy";
//Constant Holidays
NSDate *newYearsDay = [formatter dateFromString:[NSString stringWithFormat:#"1/1/%#",nextYear]]; //Use next year for the case where we are adding days near end of december.
NSDate *indDay = [formatter dateFromString:[NSString stringWithFormat:#"7/4/%#",year]];
NSDate *vetDay = [formatter dateFromString:[NSString stringWithFormat:#"11/11/%#",year]];
NSDate *xmasDay = [formatter dateFromString:[NSString stringWithFormat:#"12/25/%#",year]];
//Variable Holidays
NSInteger currentYearInt = [[[NSCalendar currentCalendar]
components:NSYearCalendarUnit fromDate:[NSDate date]] year];
NSDate *mlkDay = [self getTheNth:3 occurrenceOfDay:2 inMonth:1 forYear:currentYearInt];
NSDate *presDay = [self getTheNth:3 occurrenceOfDay:2 inMonth:2 forYear:currentYearInt];
NSDate *memDay = [self getTheNth:5 occurrenceOfDay:2 inMonth:5 forYear:currentYearInt]; // Let's see if there are 5 Mondays in May
NSInteger month = [[[NSCalendar currentCalendar] components:NSYearCalendarUnit fromDate:memDay] month];
if (month > 5) { //Check that we are still in May
memDay = [self getTheNth:4 occurrenceOfDay:2 inMonth:5 forYear:currentYearInt];
}
NSDate *labDay = [self getTheNth:1 occurrenceOfDay:2 inMonth:9 forYear:currentYearInt];
NSDate *colDay = [self getTheNth:2 occurrenceOfDay:2 inMonth:10 forYear:currentYearInt];
NSDate *thanksDay = [self getTheNth:4 occurrenceOfDay:5 inMonth:11 forYear:currentYearInt];
return #[newYearsDay,mlkDay,presDay,memDay,indDay,labDay,colDay,vetDay,thanksDay,xmasDay];
}
-(NSDate *)getTheNth:(NSInteger)n occurrenceOfDay:(NSInteger)day inMonth:(NSInteger)month forYear:(NSInteger)year{
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
dateComponents.year = year;
dateComponents.month = month;
dateComponents.weekday = day; // sunday is 1, monday is 2, ...
dateComponents.weekdayOrdinal = n; // this means, the first of whatever weekday you specified
return [[NSCalendar currentCalendar] dateFromComponents:dateComponents];
}
#end

How can I compare two dates, return a number of days

how can I compare two dates return number of days.
Ex: Missing X days of the Cup.
look my code.
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"d MMMM,yyyy"];
NSDate *date1 = [df dateFromString:#"11-05-2010"];
NSDate *date2 = [df dateFromString:#"11-06-2010"];
NSTimeInterval interval = [date2 timeIntervalSinceDate:date1];
//int days = (int)interval / 30;
//int months = (interval - (months/30)) / 30;
NSString *timeDiff = [NSString stringWithFormat:#"%dMissing%d days of the Cup",date1,date2, fabs(interval)];
label.text = timeDiff; // output (Missing X days of the Cup)
From Apple's example, basically use an NSCalendar:
NSDate * date1 = <however you initialize this>;
NSDate * date2 = <...>;
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags
fromDate:date1
toDate:date2 options:0];
NSInteger months = [components month];
NSInteger days = [components day];
You can use next category:
#interface NSDate (Additions)
-(NSInteger)numberOfDaysUntilDay:(NSDate *)aDate;
-(NSInteger)numberOfHoursUntilDay:(NSDate *)aDate;
#end
#implementation NSDate (Additions)
const NSInteger secondPerMunite = 60;
const NSInteger munitePerHour = 60;
const NSInteger hourPerDay = 24;
-(NSInteger)numberOfDaysUntilDay:(NSDate *)aDate
{
NSInteger selfTimeInterval = [aDate timeIntervalSinceDate:self];
return abs(selfTimeInterval / (secondPerMunite * munitePerHour * hourPerDay));
}
-(NSInteger)numberOfHoursUntilDay:(NSDate *)aDate
{
NSInteger selfTimeInterval = [aDate timeIntervalSinceDate:self];
return abs(selfTimeInterval / (secondPerMunite * munitePerHour));
}
#end
Need to call this method and set 2 dates only which we want to calculate differently.
-(void) calculateSleepHours:(NSDate *)sleepDate :(NSDate *)wakeStr
{
if (sleepDate !=nil && wakeStr!=nil) {`enter code here`
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateFormat:#"yyyy-MM-dd HH:mm:ssZ"];
NSDate *date1 = [ApplicationManager getInstance].sleepTime;;
NSDate *date2 = [ApplicationManager getInstance].wakeupTime;
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags
fromDate:date1
toDate:date2 options:0];
NSInteger months = [components month];
NSInteger days = [components day];
NSInteger hours = [components hour];
NSInteger minute=[components minute];
NSInteger second=[components second];
DLog(#"Month %ld day %ld hour is %ld min %ld sec %ld ",(long)months,(long)days,(long)hours,(long)minute,(long)second);
sleepHours.text=[NSString stringWithFormat:#"Hour %ld Min %ld Sec %ld",(long)hours,(long)minute,(long)second];
}
}
Try this category:
#interface NSDate (DateUtils)
-(NSInteger)numberOfDaysUntilDay:(NSDate *)aDate;
#end
#implementation NSDate (DateUtils)
-(NSInteger)numberOfDaysUntilDay:(NSDate *)aDate
{
NSCalendar *calendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [calendar components:NSCalendarUnitDay
fromDate:self
toDate:aDate options:kNilOptions];
return [components day];
}
#end
You can use this category by adding an import:
#import "NSDate+DateUtils.h"
And call it from your code:
NSInteger days = [myDate numberOfDaysUntilDay:someOtherDate];

Comparing dates [duplicate]

I have two dates: 2009-05-11 and the current date. I want to check whether the given date is the current date or not. How is this possible.
Cocoa has couple of methods for this:
in NSDate
– isEqualToDate:
– earlierDate:
– laterDate:
– compare:
When you use - (NSComparisonResult)compare:(NSDate *)anotherDate ,you get back one of these:
The receiver and anotherDate are exactly equal to each other, NSOrderedSame
The receiver is later in time than anotherDate, NSOrderedDescending
The receiver is earlier in time than anotherDate, NSOrderedAscending.
example:
NSDate * now = [NSDate date];
NSDate * mile = [[NSDate alloc] initWithString:#"2001-03-24 10:45:32 +0600"];
NSComparisonResult result = [now compare:mile];
NSLog(#"%#", now);
NSLog(#"%#", mile);
switch (result)
{
case NSOrderedAscending: NSLog(#"%# is in future from %#", mile, now); break;
case NSOrderedDescending: NSLog(#"%# is in past from %#", mile, now); break;
case NSOrderedSame: NSLog(#"%# is the same as %#", mile, now); break;
default: NSLog(#"erorr dates %#, %#", mile, now); break;
}
[mile release];
Here buddy. This function will match your date with any specific date and will be able to tell whether they match or not. You can also modify the components to match your requirements.
- (BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 {
NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];
return [comp1 day] == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year] == [comp2 year];}
Regards,
Naveed Butt
NSDate *today = [NSDate date]; // it will give you current date
NSDate *newDate = [NSDate dateWithString:#"xxxxxx"]; // your date
NSComparisonResult result;
//has three possible values: NSOrderedSame,NSOrderedDescending, NSOrderedAscending
result = [today compare:newDate]; // comparing two dates
if(result==NSOrderedAscending)
NSLog(#"today is less");
else if(result==NSOrderedDescending)
NSLog(#"newDate is less");
else
NSLog(#"Both dates are same");
There are other ways that you may use to compare an NSDate objects. Each of the
methods will be more efficient at certain tasks. I have chosen the compare method
because it will handle most of your basic date comparison needs.
This category offers a neat way to compare NSDates:
#import <Foundation/Foundation.h>
#interface NSDate (Compare)
-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
//- (BOOL)isEqualToDate:(NSDate *)date; already part of the NSDate API
#end
And the implementation:
#import "NSDate+Compare.h"
#implementation NSDate (Compare)
-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
return !([self compare:date] == NSOrderedAscending);
}
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
return ([self compare:date] == NSOrderedDescending);
}
-(BOOL) isEarlierThan:(NSDate*)date {
return ([self compare:date] == NSOrderedAscending);
}
#end
Simple to use:
if([aDateYouWantToCompare isEarlierThanOrEqualTo:[NSDate date]]) // [NSDate date] is now
{
// do your thing ...
}
If you make both dates NSDates you can use NSDate's compare: method:
NSComparisonResult result = [Date2 compare:Date1];
if(result==NSOrderedAscending)
NSLog(#"Date1 is in the future");
else if(result==NSOrderedDescending)
NSLog(#"Date1 is in the past");
else
NSLog(#"Both dates are the same");
You can take a look at the docs here.
By this method also you can compare two dates
NSDate * dateOne = [NSDate date];
NSDate * dateTwo = [NSDate date];
if([dateOne compare:dateTwo] == NSOrderedAscending)
{
}
The best way I found was to check the difference between the given date and today:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* now = [NSDate date];
int differenceInDays =
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] -
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now];
According to Listing 13 of Calendrical Calculations in Apple's Date and Time Programming Guide [NSCalendar ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:myDate] gives you the number of midnights since the start of the era.
This way it's easy to check whether the date is yesterday, today, or tomorrow.
switch (differenceInDays) {
case -1:
dayString = #"Yesterday";
break;
case 0:
dayString = #"Today";
break;
case 1:
dayString = #"Tomorrow";
break;
default: {
NSDateFormatter* dayFormatter = [[NSDateFormatter alloc] init];
[dayFormatter setLocale:usLocale];
[dayFormatter setDateFormat:#"dd MMM"];
dayString = [dayFormatter stringFromDate: date];
break;
}
}
NSDateFormatter *df= [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate *dt1 = [[NSDate alloc] init];
NSDate *dt2 = [[NSDate alloc] init];
dt1=[df dateFromString:#"2011-02-25"];
dt2=[df dateFromString:#"2011-03-25"];
NSComparisonResult result = [dt1 compare:dt2];
switch (result)
{
case NSOrderedAscending: NSLog(#"%# is greater than %#", dt2, dt1); break;
case NSOrderedDescending: NSLog(#"%# is less %#", dt2, dt1); break;
case NSOrderedSame: NSLog(#"%# is equal to %#", dt2, dt1); break;
default: NSLog(#"erorr dates %#, %#", dt2, dt1); break;
}
Enjoy coding......
In Cocoa, to compare dates, use one of isEqualToDate, compare, laterDate, and earlierDate methods on NSDate objects, instantiated with the dates you need.
Documentation:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/isEqualToDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/earlierDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/laterDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/compare:
What you really need is to compare two objects of the same kind.
Create an NSDate out of your string date (#"2009-05-11") :
http://blog.evandavey.com/2008/12/how-to-convert-a-string-to-nsdate.html
If the current date is a string too, make it an NSDate. If its already an NSDate, leave it.
Here's the Swift variant on Pascal's answer:
extension NSDate {
func isLaterThanOrEqualTo(date:NSDate) -> Bool {
return !(self.compare(date) == NSComparisonResult.OrderedAscending)
}
func isEarlierThanOrEqualTo(date:NSDate) -> Bool {
return !(self.compare(date) == NSComparisonResult.OrderedDescending)
}
func isLaterThan(date:NSDate) -> Bool {
return (self.compare(date) == NSComparisonResult.OrderedDescending)
}
func isEarlierThan(date:NSDate) -> Bool {
return (self.compare(date) == NSComparisonResult.OrderedAscending)
}
}
Which can be used as:
self.expireDate.isEarlierThanOrEqualTo(NSDate())
Here's the function from Naveed Rafi's answer converted to Swift if anyone else is looking for it:
func isSameDate(#date1: NSDate, date2: NSDate) -> Bool {
let calendar = NSCalendar()
let date1comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date1)
let date2comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date2)
return (date1comp.year == date2comp.year) && (date1comp.month == date2comp.month) && (date1comp.day == date2comp.day)
}
Get Today's Date:
NSDate* date = [NSDate date];
Create a Date From Scratch:
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.year = 2015;
comps.month = 12;
comps.day = 31;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* date = [calendar dateFromComponents:comps];
Add a day to a Date:
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = 1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* tomorrow = [calendar dateByAddingComponents:comps toDate:date options:nil];
Subtract a day from a Date:
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = -1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* yesterday = [calendar dateByAddingComponents:comps toDate:date options:nil];
Convert a Date to a String:
NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MMMM dd, yyyy";
NSString* dateString = [formatter stringFromDate:date];
Convert a String to a Date:
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MMMM dd, yyyy";
NSDate* date = [formatter dateFromString:#"August 02, 2014"];
Find how many days are in a month:
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSRange currentRange = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
NSInteger numberOfDays = currentRange.length;
Calculate how much time something took:
NSDate* start = [NSDate date];
for(int i = 0; i < 1000000000; i++);
NSDate* end = [NSDate date];
NSTimeInterval duration = [end timeIntervalSinceDate:start];
Find the Day Of Week for a specific Date:
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSInteger dow = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];
Then use NSComparisonResult to compare date.
..
NSString *date = #"2009-05-11"
NSString *nowDate = [[[NSDate date]description]substringToIndex: 10];
if([date isEqualToString: nowDate])
{
// your code
}