NSDateFormatter, am I doing something wrong or is this a bug?

16,217

Solution 1

Using the code you posted on both the simulator and a phone with the 2.1 firmware and 24-hour time set to off, I never had an AM/PM appended to dateStr when I do:

NSLog(@"%@", dateStr);

Are you doing anything else with dateStr that you didn't post here? How are you checking the value?

Follow up

Try turning the am/pm setting on then off. I didn't have the problem either, until I did that. I am printing it out the same way you are.

Okay, I see it when I do this also. It's gotta be a bug. I recommend you file a bug report and just check for and filter out the unwanted characters in the meantime.

Solution 2

The reason for this behaviour is Locale, It sets the correct Locale.

Set the local of your NSDateFormatter to en_US_POSIX will fix this. It works for both 24-hour and 12 hour format.

On iPhone OS, the user can override the default AM/PM versus 24-hour time setting (via Settings > General > Date & Time > 24-Hour Time), which causes NSDateFormatter to rewrite the format string you set. From apple doc

Try this,

NSDate *today = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
NSString *dateStr = [dateFormatter stringFromDate:today];

Solution 3

Here's the explanation of the iPhone SDK bug (also still there in 3.1 beta SDK)

First, a little background on the iPhone user interface. When iPhone users change their region format between, say, “United States” and “France”, the users’ “24-Hour Time” setting is automatically switched to the mode that is most prevalent in that region. In France, that would set 24-Hour Time to “ON”, and in the U.S., that would set it to “OFF”. The users can then manually override that setting and that’s where trouble starts.

The problem comes from NSDateFormatter somehow “getting stuck” in the 12 or 24-hour time mode that the user has manually selected. So if a French user manually selects 12-hour mode, and the application requested NSDateFormatter to output time with the 24-hour format “HHmm”, it would actually receive time in a 12-hour format, e.g. “01:00 PM”, as if the application had instead requested “hhmm aa”. The reverse would happen if a US user manually selected 24-hour mode: outputting time with the 12-hour format “hhmm aa” would actually get you time in the 24-hour format instead, e.g. “17:00″.

More details and a possible workaround can be found on this blog.

Solution 4

Setting locale on date formatter to en_US fixes the problem for me:

    NSDateFormatter * f = [[NSDateFormatter alloc] init];
    [f setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    f.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
    f.calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
    f.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];

I'm not sure if adding the calendar is also needed, but this works well.

Solution 5

I think this is the solution .

NSDateFormatter *df =[[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

[df setLocale: usLocale];

[usLocale release];

 NSDate *documento_en_Linea =[[[NSDate alloc] init]autorelease];

documento_en_Linea=[df dateFromString:@"2010-07-16 21:40:33"];

[df release];

        NSLog(@"fdocumentoenLineaUTC:%@!",documento_en_Linea);


//ouput  
     fdocumentoenLineaUTC:2010-07-16 09:40:33 p.m. -0500!
Share:
16,217
Tetaxa
Author by

Tetaxa

Java, Objective-C, Rails developer...in roughly that order.

Updated on June 03, 2022

Comments

  • Tetaxa
    Tetaxa almost 2 years

    I'm trying to print out the date in a certain format:

    NSDate *today = [[NSDate alloc] init];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
    NSString *dateStr = [dateFormatter stringFromDate:today];
    

    If the iPhone is set to 24 hour time, this works fine, if on the other hand the user has set it to 24 hour time, then back to AM/PM (it works fine until you toggle this setting) then it appends the AM/PM on the end even though I didn't ask for it:

    20080927030337 PM
    

    Am I doing something wrong or is this a bug with firmware 2.1?

    Edit 1: Made description clearer

    Edit 2 workaround: It turns out this is a bug, to fix it I set the AM and PM characters to "":

    [dateFormatter setAMSymbol:@""];
    [dateFormatter setPMSymbol:@""];