Make the date understandable

February 20th, 2015 posted in Apps Developement Objective-C

Dates, they really suck. What I mean is dates can be written many ways. Just mentioning TimeZone or date localization will make even the best programmers shake.
A date written like 3-2-2014 can mean different thing in different parts of the world. In most European countries it would mean the 3 of february 2014 but in the USA it’s the march 2 2014. And then we just covered the numeric date representation.

How does one solve this, in a way that the user isn’t easily confused. You could just write out the hole date, but there isn’t always room for that in you interface.

Presenting

Well luckily Apple has made it easy for you to present a date in some format (small, medium, large and full) that the user will understand. This is because the date are represented in the user local format. No longer will your user be confused by date if you use the default format style for you date representation.

So lest start:

 
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];    
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];[dateFormatter setDateStyle:NSDateFormatterNoStyle]; 
NSString *dateString = [dateFormatter stringFromDate:someDate];

Well that look really simple right and it is, the date will now be formatted with the users localization settings.
Let’s say that the someDate is 1 januari 2014 13:00 GMT, lets see how it looks


US style 1:00 PM
Most European styles 13:00

Keep in mind that allocing a object takes time and in this case 4 lines of code, luckily Apple even thought about this and there is a shorter way of doing it:

 
NSString *dateString = [NSDateFormatter localizedStringFromDate:someDate 
                                                      dateStyle:NSDateFormatterNoStyle 
                                                      timeStyle:NSDateFormatterShortStyle];

Here are some example of the styles on my system, using a US locale:
Short: 12/1/14, 2:00 PM
Medium: Dec 1, 2014, 2:00:00 PM
Long: December 1, 2014 at 2:00:00 PM GMT+1
Full: Monday, December 1, 2014 at 2:00:00 PM Central European Standard Time

Parsing

Parsing is where things become difficult, as many post on stack overflow will tell you. Most of which are about localized dates.
Localized dates are not very useful on the internet, since it is international and localized date can be mis interpreted. For some weird reason some API will have localized date instead of a ISO or RFC standaard date. Lets see an example:

sun 1 december 2013 2:00 PM

Well this is difficult to parse, since the system will need to know the language is which the date is presented. So we will have to tell the NSDateFormatter the language used, which is identified by it locale:

NSString *dateToParse = @"sun 1 december 2013 2:00 PM";
 
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];dateFormatter.dateFormat = @"EE d MMMM yyyy h:mm a";
 
NSDate *date = [dateFormatter dateFromString:dateToParse];

In this example you can clearly see that the date is localized, so we tell the date formatter that it locale that is used is english. The date formatter will now understand that the date contains english words.

Please always set the locale is you are parsing localized dates, because if the localized date does not match the systems locale the parsing will fail.

You will find a full list of unicode date time format code here: http://www.unicode.org/reports/tr35/tr35-25.html#Date_Field_Symbol_Table

Timezones

Now a detail about NSDate, NSDate does not know anything about timezones. It is always GMT. Thus when you run the above code the time might off. It is not really off but the the time is offset to the users timezone.

When parsing the date, without any time zone, the users time zone is used. If we run the example above and print the date you could and up with

2014-12-01 13:00:00 +0000

This is because my systems time zone is +0100.