-2

I need to compare the current date/time against user selected date/time. Below is my code snippet

-(IBAction)btnSaveTouched:(id)sender {
NSDate *today = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd H:mm"];
NSString *formatterDate = [formatter stringFromDate: today];

NSComparisonResult comparisionResult1 = [self.paramSchedule1StartSQLDateString compare:formatterDate];

if (comparisionResult1 == NSOrderedAscending) {

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Viewing schedule must be after current time." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    return;
} 

NSLog(@"comparisionResult1 %d", comparisionResult1);

}

After btnSaveTouched(UIButton) is tap, the date/time will be store into the database and return back to the screen. (view controller where user select the date/time)

However, when I tried to compare another date/time, the alert will be show even though I selected date/time later then the current date/time.

After NSLog the comparsionResult1, the value is 1 for the second time checking always. I tried to do this NSComparsionResult comparisionResult1 = 0; but it's not working properly. Is there any ways to go about doing this?

Please advise. Thanks

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Sara Tan
  • 23
  • 1
  • 1
  • 1
  • Add a log statement that shows both date strings. This way you can see exactly what is being compared. BTW - it would be *much* better if you compared two `NSDate` objects and not two date strings. – rmaddy Jun 25 '13 at 17:24
  • If you insist on using date strings, it would help if you used a 2-digit hour. Use `HH` instead of `H`. – rmaddy Jun 25 '13 at 17:25
  • Hi, I NSLog both date which is 2013-06-26 1:23 (current date) and 2013-06-28 9:25 (user chosen date). by right it shouldn't go into the if statement. – Sara Tan Jun 25 '13 at 17:27
  • You can compare dates in a number of ways. Obviously, if you compare strings you must make sure the fields in the string are arranged in order of significance. Further, you need to assure that they are the same width, so that "10:00" compares after "9:00" (by expanding the "9:00" to "09:00"). And using formatted dates you can get bit by the [locale "feature"](http://stackoverflow.com/questions/6613110/what-is-the-best-way-to-deal-with-the-nsdateformatter-locale-feature) if you're not careful. But comparing NSDate objects has a few pitfalls as well. – Hot Licks Jun 25 '13 at 17:28
  • hi, what's the best way of comparing both dates? Will want to ensure that user doesn't choose date/time that is early then the current date/time. – Sara Tan Jun 25 '13 at 17:29
  • (A further point of confusion is that the `NSOrderedAscending`, et al, values are ambiguous at best, and easy to get reversed.) – Hot Licks Jun 25 '13 at 17:30
  • @SaraTan The two date strings you mention in your comment means that `comparisionResult1` will be equal to `NSOrderedDescending`. Since you state that the log shows a value of 1, then this is in fact the case since `NSOrderedDescending` has a value of 1. Is the `if` statement you posted in your question pasted exactly from the real code? – rmaddy Jun 25 '13 at 17:34
  • Frankly, the least confusing way to compare two NSDate objects is `if ([date1 timeIntervalSinceReferenceDate] > [date2 timeIntervalSinceReferenceDate])...`. Or create categories on NSDate for yourself that are `-(BOOL) isBefore:(NSDate*) date2`, etc. – Hot Licks Jun 25 '13 at 17:34
  • @HotLicks `NSOrderedAscending` et al are perfectly straightforward. If `[a compare:b]` returns ascending then the list `a, b` is ascending. Just remember that you've written the two objects left-to-right to make the call. – Tommy Jun 25 '13 at 17:37
  • hi. thanks for the reply. the code pasted is the exact code i'm running. thats the puzzling part. wonder why it will return 1 the second time it check the date – Sara Tan Jun 25 '13 at 17:42
  • @Tommy - The problem is that it's very hard to remember whether it means that b is ascending relative to a or a is ascending relative to b, and it gets even harder when embedded in an if statement with a bunch of other conditions. Then add in using a `!=` instead of an `==` and things get totally beyond conceptual control. – Hot Licks Jun 25 '13 at 17:44
  • @HotLicks I disagree. If it were phrased as `[@[a, b] compare]` you'd have no difficulty as a and b are written left-to-right. Well, `[a compare:b]` is exactly the same. They're ascending if, in the order you've written them on your screen, they are ascending. Just literally read the text on your screen. That being said, a lot of people seem to find it confusing so I don't suppose my argument stands up that well. – Tommy Jun 25 '13 at 17:49
  • @HotLicks ... and I've definitely met people who swear by the standard project setup of adding a `Comparisons` category to `NSObject`, or similar, that simply provides `- (BOOL)isGreaterThan:(id)object`, etc, implemented as `return [self compare:object] == NSOrderedDescending;` and so on. – Tommy Jun 25 '13 at 17:55

3 Answers3

10

Comparison between dates you need to be careful, expecially If you compare with NSString, you must make sure both dates are arranged, and you need to be careful with both formats..So i recomend you compare two NSDate. Sample:

NSDate *date1 = //…
NSDate *date2 = //…
switch ([date1 compare:date2]) {
    case NSOrderedAscending:
    //Do your logic when date1 < date2
        break;

    case NSOrderedDescending:
    //Do your logic when date1 > date2
        break;

    case NSOrderedSame:
    //Do your logic when date1 = date2
        break;
}

Of course, you can implement a category for NSDate. But already exists, and i like to use this one: NSDate Category, witch you can edit and customize as you wish.

3

Try this code for any comparison between dates... You should not compare date in the form of string. Compare the dates before conversion to string. Convert the self.paramSchedule1StartSQLDateString into date format using dateFromString function of the formatter by specifying the exact date format as that of the dateString. Then compare the dates using following function.

NSDate *today = [NSDate date]; // current date
NSDate *newDate = self.paramSchedule1StartSQLDateString; // other date 

NSComparisonResult result; 

result = [today compare:newDate]; // comparing two dates

if(result == NSOrderedAscending)
    NSLog(@"today is less");
else if(result == NSOrderedDescending)
    NSLog(@"newDate is less");
else if(result == NSOrderedSame)
    NSLog(@"Both dates are same");
else
    NSLog(@"Date cannot be compared");
prince
  • 854
  • 2
  • 9
  • 36
2
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
                [dateFormatter setDateFormat:@"yyyy-MM-dd"];
                NSDate *date1 = [dateFormatter dateFromString:TodayDate];

                NSDateFormatter *dateFormatte = [[[NSDateFormatter alloc] init] autorelease];
                [dateFormatte setDateFormat:@"yyyy-MM-dd"];
                NSDate *date2 = [dateFormatte dateFromString:CompareDate];

                unsigned int unitFlags = NSDayCalendarUnit;

                NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
                NSDateComponents *comps = [gregorian components:unitFlags fromDate:date1  toDate:date2  options:0];

                int days = [comps day];
                NSLog(@"%d",days);
Bhavesh Nayi
  • 3,626
  • 1
  • 27
  • 42