Comparing Current Date To Written Date (time stamp string file)?

Discussion in 'Mac Programming' started by Darkroom, Jul 21, 2008.

  1. Darkroom Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #1
    i'm having problems comparing a written time stamp file (that is a string of the date when the file was written, IE:"2008-07-21 13:49:53 -0400") with the current date in an if statement. i'm not sure if i can ask if the current date is before or after the date file, because well, dates are more before or after, not greater than or less than... maybe greater than/less than is the same as before and after and i'm looking at this the wrong way, but i just can't seem to get it right.

    Code:
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *installDateFile = @"~/Desktop/dateFile.txt";
    installDateFile = [installDateFile stringByExpandingTildeInPath];
    NSDate *currentDate = [NSDate date];
    
    if ([fileManager fileExistsAtPath: installDateFile] == NO)
    	{
    	NSString *installDate = [[NSDate date] descriptionWithCalendarFormat:nil timeZone:nil locale:nil];
    	[installDate writeToFile:installDateFile atomically:YES encoding:NSUnicodeStringEncoding error:NULL];
    
            if (currentDate <= installDateFile)
    	        {
    	        NSLog (@"Installed Date File Is In The Future");
    	        }
                    else
                    {
                    NSLog (@"Installed Date File Is In The Past");
                    }
    }
    
    thoughts?
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    Number one thought:
    ==, <, >, <=, >= operators only work on primitives. Anything else you are using these on is just doing pointer comparisons, and this is very rarely what you want to do.

    From the NSDate documentation:
    Comparing Dates
    – isEqualToDate:
    – earlierDate:
    – laterDate:
    – compare:

    All of these take another NSDate and return various things. earlierDate and laterDate return either the receiver or the parameter based on which is earlier or later. compare: returns an NSComparisonResult. isEqualToDate: returns a BOOL.

    I'm thinking you want some metadata about a file, but you are currently comparing the pointer to an NSDate to a pointer to an NSString. Someone else might know off the top of their head the cocoa way to get metadata about a file. It seems like NSFileManager's:
    Code:
    - (NSDictionary *)attributesOfItemAtPath:(NSString *)patherror:(NSError **)error
    will get you a dictionary with:
    http://developer.apple.com/document...le_ref/doc/constant_group/File_Attribute_Keys

    from which you can get an NSDate for modification date and create date.

    -Lee

    Edit: Just wanted to point out more specifically that Objective-C does not allow for operator overloading like Fortran 90/95 (don't know which revision added this) or C++. This is why you should essentially strike the primitive comparator's from your programming vocabulary unless you have a couple of ints your comparing or something typedef'd to a primitive like NSUInteger.
     
  3. Darkroom thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #3
    so i guess writing if (currentDate earlierDate:installDateFile) shouldn't work either?
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    No good.

    The only method that returns a BOOL is isEqualToDate:. So you could either use that along with a earlierDate or laterDate call. Or use compare: and THEN use == to compare to NSOrderedAscending, NSOrderedDescending, or NSOrderedSame. These are defined in an enum as constants, so they are just shortcuts to int primitives (-1,0,1).

    So with some assumptions:
    Code:
    - (BOOL)dateLessThan:(NSDate *)aDate Date:(NSDate *)bDate {
      BOOL result = false;
      if([aDate compare:bDate] == NSOrderedAscending) result = true;
      return result;
    }
    
    - (BOOL)dateEqualTo:(NSDate *)aDate Date:(NSDate *)bDate {
      BOOL result = false;
      if([aDate compare:bDate] == NSOrderedSame) result = true;
      return result;
    }
    
    - (BOOL)dateGreaterThan:(NSDate *)aDate Date:(NSDate *)bDate {
      BOOL result = false;
      if([aDate compare:bDate] == NSOrderedDescending) result = true;
      return result;
    }
    
    -Lee
     
  5. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #5
    Wrote up a quick sample to make sure what I was saying compiles and works:
    Code:
    #import <Foundation/Foundation.h>
    
    int main (int argc, const char * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
        NSDate *dateOne = [NSDate date];
    	sleep(3);
    	NSDate *dateTwo = [NSDate date];
    	switch ([dateOne compare:dateTwo]) {
    	  case NSOrderedSame:
    	    NSLog(@"These dates are the same!");
    		break;
    	  case NSOrderedAscending:
    	    NSLog(@"dateOne is earlier than dateTwo!");
    	    break;
    	  case NSOrderedDescending:
    	    NSLog(@"dateTwo is earlier than dateOne!");
    	    break;
    	  default:
    	    NSLog(@"Bad times. Invalid enum value returned.");
    		break;
    	}
    	
        [pool release];
        return 0;
    }
    Obviously there is only one code path right now that executes, but it should illustrate the point. The switch is used in the place of if-then-else-if-then-else-then clutter, but the usage is the same as doing that with ==.

    -Lee
     
  6. Darkroom thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada

Share This Page