This question already has answers here:
How to Check if an NSDate occurs between two other NSDates
(10 answers)
Closed 9 years ago.
I want to check if current date is between two given dates. I do the following
NSDate *now = [NSDate new];
NSLog(#"Now is %#",now);
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
[components setYear:2013];
[components setMonth:06];
[components setDay:28];
[components setHour:5];
[components setMinute:00];
NSDate *startDate1 = [myCalendar dateFromComponents:components];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.timeZone = [NSTimeZone localTimeZone];
formatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
NSLog(#"start dateeee is %#",startDate1);
NSDateComponents* components2 = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
[components2 setYear:2013];
[components2 setMonth:06];
[components2 setDay:29];
[components2 setHour:4];
[components2 setMinute:59];
NSDate *endDate1 = [myCalendar dateFromComponents:components];
NSLog(#"end date is %#",endDate1)
;
Now I have created 2 dates Startdate1 and endDate1. For to check if the current date is between those to dates I am doing this.
NSComparisonResult result1 = [now compare:startDate1];
NSComparisonResult result2 = [now compare:endDate1];
if (result2 == NSOrderedSame && result1 == NSOrderedSame ) {
NSLog(#"HELL YEAH! ");
}
But I never get a HELL YEAH ??
NOTE: I have set my iPhone datetime to a time between the start and enddate. Also here are my LOGS:
2013-06-29 11:11:48.727 Genk on stage[2205:907] Now is 2013-06-29 09:11:48 +0000
2013-06-29 11:11:48.728 Genk on stage[2205:907] start dateeee is 2013-06-28 03:00:00 +0000
2013-06-29 11:11:48.729 Genk on stage[2205:907] end date is 2013-06-28 03:00:00 +0000
Your logic is flawed. The return value NSOrderedSame means that two values compared equal. That's not what you want. Instead, you want to check if the first date comes before the current date and the second one comes after it:
if (result1 == NSOrderedAscending && result2 == NSOrderedDescending)
is what you should write.
change your code to
if (result2 == NSOrderedDescending && result1 == NSOrderedAscending ) {
NSLog(#"HELL YEAH! ");
}
This might solve your problem
Happy coding :)
NSDate * now;.....
NSDate * endDate1;......
if ([now compare: endDate1] == NSOrderedDescending) {
NSLog(#"now is later than endDate1");
} else if ([now compare: endDate1] == NSOrderedAscending) {
NSLog(#"now is earlier than endDate1");
} else {
NSLog(#"dates are the same");
}
You can use the following code.
NSTimeInterval fromTime = [startDate1 timeIntervalSinceReferenceDate];
NSTimeInterval toTime = [endDate1 timeIntervalSinceReferenceDate];
NSTimeInterval currTime = [[NSDate date] timeIntervalSinceReferenceDate];
if(currTime>fromTime && currTime<toTime)
{
//current time lies between the two dates
}
You can check this using this :
- (BOOL)yourDate:(NSDate *)date inRangeFirstDate:(NSDate *)startDate lastDate:(NSDate *)endDate {
return [date compare:startDate] == NSOrderedDescending &&
[date compare:endDate] == NSOrderedAscending;
}
If it returns YES then yourDate lies between the startDate and endDate else it returns NO.
Hope it helps you
Related
Why is this giving me the wrong date ?
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
[components setYear:2013];
[components setMonth:06];
[components setDay:28];
[components setHour:5];
[components setMinute:00];
NSDate *startDate1 = [myCalendar dateFromComponents:components];
NSLog(#"start date is %#",startDate1);
start date is 2013-06-28 03:00:00 +0000
EDIT
What I want to do is the following. I have a start and endate.
For example:
start date is 2013-06-28 05:00
end date is : 2013-06-29 04:59
Then I want to check if the current date is between start and end date. I am using the following.
NSComparisonResult result1 = [now compare:startDate1];
NSComparisonResult result2 = [now compare:endDate1];
if (result2 == NSOrderedSame && result1 == NSOrderedSame ) {
NSLOG(#"OKE!");
}
Probably the date is correct, but you misunderstood the log:
Logging a date is always done in TZ +0000. For example, if you are in central europe, you will have the (expected?) date 2013-06-28 05:00:00 +0200, but the log will display the normilzed date 2013-06-28 03:00:00 +0000. This is the same date and time! It is simply expressed in a different way.
+++
If your components are in TZ +0000, too, you should set the time zone of the calendar.
You can check whether the current date is between two dates like this:
NSDate *now = [NSDate date];
BOOL betweenStartAndEnd = ([startDate compare:now] == NSOrderedAscending && [endDate compare:now] == NSOrderedDescending);
Your code actually checks whether the tested date is EQUAL (NSOrderedSame) to both start and end dates (which is not of course)
result2 == NSOrderedSame && result1 == NSOrderedSame
See my extended example:
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
[components setYear:2013];
[components setMonth:05];
[components setDay:13];
[components setHour:18];
[components setMinute:00];
NSDate *startDate = [myCalendar dateFromComponents:components];
[components setDay:15];
NSDate *endDate = [myCalendar dateFromComponents:components];
NSDate *now = [NSDate date];
BOOL betweenStartAndEnd = ([startDate compare:now] == NSOrderedAscending && [endDate compare:now] == NSOrderedDescending);
NSLog(#"Date %# %# between %# and %#", now, betweenStartAndEnd ? #"IS" : #"IS NOT", startDate, endDate);
This prints out this to the console:
Date 2013-05-13 15:44:06 +0000 IS NOT between 2013-05-13 16:00:00 +0000 and 2013-05-15 16:00:00 +0000
That's because you have to print the date using device's time zone, otherwise it's shown in UTC.
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
[components setYear:2013];
[components setMonth:06];
[components setDay:28];
[components setHour:5];
[components setMinute:00];
NSDate *startDate1 = [myCalendar dateFromComponents:components];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.timeZone = [NSTimeZone systemTimeZone];
formatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
NSLog(#"%#", [formatter stringFromDate:startDate1]);
I know how to compare dates.In my case, let Date1 = 2011-10-14 & Date2 =2011-10-20 .And I want to check if 15th Oct lie between Date1 and Date2.I'm using following codes for this:
if ( [date compare:Date1] == NSOrderedDescending && [date compare:Date2] == NSOrderedAscending) {
//write codes
}
But this will not check if 15th oct lie between 14th and 20th Oct.rather it check for whole date. So, How will I implement this.
Thnx in advance.
I hope the following code would help you. Assuming Date1 and Date2 you have,
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger desiredComponents = (NSDayCalendarUnit | NSMonthCalendarUnit);
NSDateComponents *firstComponents = [calendar components:desiredComponents fromDate:Date1];
NSDateComponents *secondComponents = [calendar components:desiredComponents fromDate:Date2];
NSDate *firstWOYear = [calendar dateFromComponents:firstComponents];
NSDate *SecondWOYear = [calendar dateFromComponents:secondComponents];
NSComparisonResult result = [firstWOYear compare:SecondWOYear];
if (result == NSOrderedAscending) {
//Date1 is before Date2
} else if (result == NSOrderedDescending) {
//Date1 is after Date2
} else {
//Date1 is the same day/month as Date2
}
Where date1 = 2011-10-14 and date2 =2011-10-20 and date is the date you want to check.
Do this
if([date timeIntervalSince1970] >= [date1 timeIntervalSince1970] && [date timeIntervalSince1970] <= [date2 timeIntervalSince1970])
{
NSLog(#"%# lies between and including %# and %#",date,date1,date2);
// if you just wanna check for between (not including) two dates just remove the equal signs above in condition check
}
else
NSLog(#"%# does not lie between %# and %#",date,date1,date2);
The above code will check if the date lies between and including the given two extreme dates but if you just wanna check between (but excluding) the extreme dates then simply remove the equal signs from if condition check.
Comparison ->
NSString *dateString1 = #"2011-10-14";
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"yyyy-MM-dd";
NSDate *date1 = [formatter dateFromString:dateString1];
NSString *dateString2 = #"2011-10-20";
NSDateFormatter *formatter2 = [[NSDateFormatter alloc]init];
formatter2.dateFormat = #"yyyy-MM-dd";
NSDate *date2 = [formatter2 dateFromString:dateString2];
NSString *dateString3 = #"2011-10-15";
NSDateFormatter *formatter3 = [[NSDateFormatter alloc]init];
formatter3.dateFormat = #"yyyy-MM-dd";
NSDate *date3 = [formatter3 dateFromString:dateString3];
if ([date3 compare:date1] == NSOrderedDescending && [date3 compare:date2] == NSOrderedAscending)
{
NSLog(#"%# lies b/w %# and %#",dateString3,dateString1,dateString2);
}
else
{
NSLog(#"Doesn't lie!");
}
I'm setting a timeStamp property for an object. Right now I'm just using [NSDate date]. The user might create 10 objects per day. But in the UI, I want to drop them by date. So each day will show all the objects that were created for that day. How can I do this? Right now it's trying to match the date and time, etc.
Example:
Obj1 - 2/5/12 5pm
Obj2 - 2/5/12 12pm
Obj3 - 2/4/12 6pm
Obj4 - 2/1/12 1pm
I need to be able to group those by day, one for 2/5, 2/4, and 2/1.
You can use the NSDateComponents class to be able to directly access the day, month, and year of an NSDate instance.
NSDate *someDate = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:someDate];
NSLog(#"Year: %d", [components year]);
NSLog(#"Month: %d", [components month]);
NSLog(#"Day: %d", [components day]);
Here's an NSDateComponents comparison method:
- (BOOL)isFirstCalendarDate:(NSDateComponents *)first beforeSecondCalendarDate:(NSDateComponents *)second
{
if ([first year] < [second year]) {
return YES;
} else if ([first year] == [second year]) {
if ([first month] < [second month]) {
return YES;
} else if ([first month] == [second month]) {
if ([first day] < [second day]) {
return YES;
}
}
}
return NO;
}
I haven't tested the NSDateComponents comparison method; it would benefit from unit testing.
Your question is formulated rather broadly. To get the date part of an NSDate object, as an NSString, you could use:
NSDate *dateIn = [NSDate date];
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:#"yyyy-MM-dd"];
NSString *stringOut = [fmt stringFromDate:dateIn];
[fmt release];
You can easily change the date format. If you would call this code often (e.g. in a loop) you might want to allocate and set up the date formatter only once.
I have one query regarding NSDate. I have a date i.e. "2011-10-04 07:36:38 +0000", and I want to check if this date is yesterday, or today or a future date.
How would I go about this?
Try this:
Note: Change the date format as per your need.
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MM/dd/yyyy"];
NSDate* enteredDate = [df dateFromString:#"10/04/2011"];
NSDate * today = [NSDate date];
NSComparisonResult result = [today compare:enteredDate];
switch (result)
{
case NSOrderedAscending:
NSLog(#"Future Date");
break;
case NSOrderedDescending:
NSLog(#"Earlier Date");
break;
case NSOrderedSame:
NSLog(#"Today/Null Date Passed"); //Not sure why This is case when null/wrong date is passed
break;
}
See Apple's documentation on date calculations:
NSDate *startDate = ...;
NSDate *endDate = ...;
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags
fromDate:startDate
toDate:endDate options:0];
NSInteger months = [components month];
NSInteger days = [components day];
If days is between +1 and -1 then your date is a candidate for being "today". Obviously you'll need to think about how you handle hours. Presumably the easiest thing would be to set all dates to be 00:00.00 hours on the day in question (truncate the date using an approach like this), and then use those values for the calculation. That way you'd get 0 for today, -1 for yesterday, +1 for tomorrow, and any other value would likewise tell you how far things were in the future or the past.
Use any of the folowing according to ur need,
– earlierDate:
– laterDate:
– compare:
Refer this http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html
-(NSString*)timeAgoFor:(NSString*)tipping_date
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [dateFormatter dateFromString:tipping_date];
NSString *key = #"";
NSTimeInterval ti = [date timeIntervalSinceDate:[NSDate date]];
key = (ti > 0) ? #"Left" : #"Ago";
ti = ABS(ti);
NSDate * today = [NSDate date];
NSComparisonResult result = [today compare:date];
if (result == NSOrderedSame) {
return[NSString stringWithFormat:#"Today"];
}
else if (ti < 86400 * 2) {
return[NSString stringWithFormat:#"1 Day %#",key];
}else if (ti < 86400 * 7) {
int diff = round(ti / 60 / 60 / 24);
return[NSString stringWithFormat:#"%d Days %#", diff,key];
}else {
int diff = round(ti / (86400 * 7));
return[NSString stringWithFormat:#"%d Wks %#", diff,key];
}
}
is there any way to create events for NSDate ? here is my code
NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"MMMM d, yyyy"];
NSString *dateStr = [dateFormatter stringFromDate:date];
myDate.text = dateStr;
for example if date = 12 FEB ;
myDate .text = #"Mother Day";
something like this
sure it is. You have to split the date into day and month using NSDateComponents
You could write a method like this:
- (BOOL)date:(NSDate *)date isSameAsDay:(NSInteger)day andMonth:(NSInteger)month {
NSUInteger dateFlags = NSDayCalendarUnit | NSMonthCalendarUnit;
NSDateComponents *components = [[NSCalendar currentCalendar] components:dateFlags fromDate:date];
if ([components day] == day && [components month] == month) {
return YES;
}
return NO;
}
and you would use it like this
if ([self date:[NSDate date] isSameAsDay:12 andMonth:2]) {
myDate.text = #"Mother Day";
}
This should do it:
NSDate *today = [NSDate date]; // Get ref to todays date
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents =
[gregorian components:(NSWeekdayOrdinalCalendarUnit | NSWeekdayCalendarUnit | NSMonthCalendarUnit) fromDate:today];
NSInteger weekday = [weekdayComponents weekday]; // Sun == 1, Mon == 2, Tue...
NSInteger weekdayOrdinal = [weekdayComponents weekdayOrdinal]; // First weekday month == 1 etc...
NSInteger month = [weekdayComponents month];
NSLog (#"%i %i %i", weekday, weekdayOrdinal, month);
// Mothers day is every second Sunday of May so weekday == 1, weekdayOrdinal == 2, month == 5
if ((weekday == 1) && (weekdayOrdinal == 2) && (month == 5)) {
NSLog (#"It's mothers day!");
}
[gregorian release];