6

I'm trying to debug code that makes pretty heavy use of dates which has me comparing tons of different NSDate values in the debugger. The debugger is displaying those dates in UTC format--for example:

date1 = (NSDate *) 0x01b11460 @"2012-02-15 18:55:00 +0000"

It would be a lot easier for me if it would show them in my local timezone as that is what the test code I'm debugging seems to be using.

I do have feeling that I'm missing something much more basic here so I'm hoping someone can enlighten me. Thanks in advance.

GusP
  • 2,454
  • 2
  • 23
  • 32

3 Answers3

1

While a little "hackish" you can create a subclass of NSDate and override just the

-(NSString *)description;

method to return a date formatted however you want.

The debugger isn't doing any special decoding for you, it's just calling the "description" method of the object it wants to display. A handy trick... (Which is why all my objects publish a concise description suitable for viewing in a debugger.)

Jim Hayes
  • 2,126
  • 1
  • 15
  • 21
  • A category would be better for NSDate, otherwise you'd need to use subclasses everywhere – jrturton Jun 22 '12 at 05:58
  • Except that you can't replace methods using a category, you can only add them. Since he needs to override an existing method (description), a subclass needs to be used. Yeah, it's not pretty (for the reason you state!) but I don't see any other way around it. :-( – Jim Hayes Jun 22 '12 at 07:37
  • Yes you can. See [here](http://stackoverflow.com/questions/5272451/overriding-methods-using-categories-in-objective-c) for example. Its not usually a great idea, but perfect for this situation. – jrturton Jun 22 '12 at 10:34
  • Interesting. I'm new to the iOS side but is there a way to make the category only get compiled in for non-release builds? For example, wrap the whole category in whatever the iOS equivalent of '#if DEBUG' is? If so, that would seem pretty close to ideal actually. I'll investigate tonight but figured I'd chime in in the meantime in case you guys have any thoughts. Thanks! – GusP Jun 22 '12 at 14:50
  • Thanks for the help guys. I just posted an answer (the FAQ seems to say it's better that way, I'm new on SO though so let me know if I should do it differently) that worked perfectly. – GusP Jun 23 '12 at 02:00
1

In the end, what worked best was in fact adding a Category for NSDate that just overrides the description method to return a string that represents the NSDate in my current timezone. I also made it DEBUG only as I really just need this override in place when debugging.

Here's the .h file I used:

#ifdef DEBUG

@interface NSDate (DebugHelper)

-(NSString *)description;

@end

#endif

and the .m file:

#ifdef DEBUG

#import "NSDate+DebugHelper.h"

@implementation NSDate (DebugHelper)

-(NSString *) description
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
    [dateFormatter setTimeStyle:NSDateFormatterShortStyle];
    [dateFormatter setDateStyle:NSDateFormatterShortStyle];
    return [dateFormatter stringFromDate:self];
}

@end

#endif

Thanks to Jim Hayes and jrturton for the discussion and ideas that led to this answer.

GusP
  • 2,454
  • 2
  • 23
  • 32
  • 1
    Consider putting this in `-(NSString*)debugDescription`. That is what the debugger will attempt to print (default implementation just calls `description`). See: http://stackoverflow.com/questions/9379633/nsobject-description-and-debugdescription – nall Mar 08 '13 at 03:47
0

Just did the same thing, however instead of systemTimeZone I used localTimeZone (see the docs as to why it is slightly better). Also I noticed you are alloc'ing the dateFormatter object but never releasing it which is a leak.

Here's my category method:

-(NSString *) description;
{
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init]autorelease];

    NSLocale *enUSPOSIXLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];
    [dateFormatter setLocale:enUSPOSIXLocale]; 
    [dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
    [dateFormatter setDateStyle:NSDateFormatterLongStyle];
    [dateFormatter setTimeStyle:NSDateFormatterLongStyle];

    NSString *dateString = [dateFormatter stringFromDate:self];
    return dateString;
}
software evolved
  • 4,314
  • 35
  • 45