Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Date formatter returns nil for June

I have a strange problem with those lines of code :

NSDateFormatter * df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"MMyyyy"];
NSDate * date = [df dateFromString:@"062008"];
NSLog(@"Date %@", date);

The result is :

 Date (null)

But when I change the month like this :

NSDateFormatter * df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"MMyyyy"];
NSDate * date = [df dateFromString:@"072008"];
NSLog(@"Date %@", date);

The result is :

Date 2008-06-30 23:00:00 +0000

For only the month of June (06), the date conversion from string fails !

I think, it's something related to timezone, any ideas.

Thanks

solved :

[df setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];

As I thought, it's related to timezone.

like image 499
ysn mhl Avatar asked Sep 06 '13 17:09

ysn mhl


1 Answers

Congratulations, you've found more timezone oddities! You're correct that changing your time zone will fix the issue. Let's go spelunking and see if we can figure out why!

First, we'll try and find every timezone where this weirdness happens:

NSArray *tzs = [NSTimeZone knownTimeZoneNames];
NSDateFormatter *f = [[NSDateFormatter alloc] init];
f.dateFormat = @"MMyyyy";
for (NSString *name in tzs) {
    f.timeZone = [NSTimeZone timeZoneWithName:name];
    NSDate *date = [f dateFromString:@"062008"];
    if (date == nil) {
        NSLog(@"%@", name);
    }
}

This is going to loop through all known timezones and try to parse "062008" in that time zone. If we run this, we find that it logs:

Africa/Casablanca
Asia/Karachi

So I'm guessing that you live in either Casablanca or Karachi (because by default, your NSDateFormatter is initialized with your timezone, which is why you're seeing this problem; probably Casablanca, given that you appear to be 1 hour ahead of GMT).

Let's see if we can figure out what's weird with those timezones:

$ zdump -v Africa/Casablanca
... snip ...
Africa/Casablanca  Sun Jun  1 00:00:00 2008 UTC = Sun Jun  1 01:00:00 2008 WEST isdst=1
... snip ...

$ zdump -v Asia/Karachi
... snip ...
Asia/Karachi  Sat May 31 19:00:00 2008 UTC = Sun Jun  1 01:00:00 2008 PKST isdst=1
... snip ...

Sure enough, it looks like both Casablanca and Karachi skipped the midnight hour on June 1st in 2008. Thus, you're essentially giving it an unparse-able date, and it's returning nil. In a nutshell.

In this case, the correct answer is to change your timezone (GMT is probably a great choice), because chances are this string you're parsing is not coming from user input (given its weird format), and thus should be parsed according to a standard timezone. And although I'm sure that Casablanca and Karachi are really neat places, their timezones aren't exactly common ones...

TL;DR:

Daylight Saving Time ought to be abolished.

like image 108
Dave DeLong Avatar answered Oct 13 '22 17:10

Dave DeLong