Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my NSDateFormatter sometimes return an a.m. or p.m. with yyyyMMddHHmmssSSS?

Sometimes my code is returning an a.m. or p.m. but not always. Most of the time it just returns what I expect, which is something like: 20110815170852164

But other times it's returning: 20100412010241 a.m.450

NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"yyyyMMddHHmmssSSS"];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];

What could be causing this? Specific date/time country settings on users iPhones? I have this out to thousands of people, and most aren't returning the a.m. (which is expected) but others are. WHY?

like image 493
Ethan Allen Avatar asked Aug 16 '11 00:08

Ethan Allen


3 Answers

The problem you are describing is a known bug. Check out some discussion on the problem on stackoverflow, and you can find some possible work-arounds there.

Here's an excerpt of huyz's explaination of the bug:

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″.

like image 133
mopsled Avatar answered Nov 15 '22 08:11

mopsled


Right. The solution is to explicitly set the locale of the date formatter, ideally to en_US_POSIX. See the final answer to this question.

like image 35
Hot Licks Avatar answered Nov 15 '22 08:11

Hot Licks


I was working on a data-share function of a project which was highly depending on the values/results entered in advance when I bumped into the same problem. I implemented a nasty little workaround for saving the right datetime in 24h format to the database.

The solution is very simple

First, I get the local date from the device:

NSDate* now = [NSDate date];

Second step is to create a NSDateFormatter with US locale regardless of system's locale to make sure that "PM" is going to be "PM":

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];

Then, I get the date (year, month, day) into a string:

[formatter setDateFormat:@"yyyy-MM-dd"];
NSString *date = [formatter stringFromDate:now];

For the next part, I get the hours, minutes and seconds:

[formatter setDateFormat:@"hh"];
NSString *hours = [formatter stringFromDate:now];
[formatter setDateFormat:@"mm"];
NSString *minutes = [formatter stringFromDate:now];
[formatter setDateFormat:@"ss"];
NSString *seconds = [formatter stringFromDate:now];

Next, I get the part of the day:

[formatter setDateFormat:@"a"];
NSString *partOfDay = [formatter stringFromDate:now];

Then comes the logic: if the part of the day is PM but the hours are less then 12, we just have to correct that. In code:

if([partOfDay isEqualToString:@"PM"] && [hours intValue] < 12) {
    hours = [[NSString alloc] initWithFormat:@"%i", ([hours intValue] + 12)];
}

After this modification, we are ready to put the string together in order to have a datetime ready to be saved into SQL:

NSString *sqlDateTime = [[NSString alloc] initWithFormat:@"%@ %@:%@:%@", date, hours, minutes, seconds];

That's all there is to it. And from now we can only hope that Apple is going to fix this bug to make it work as it should be.

I hope this helps.

like image 40
Barnabas Kecskes Avatar answered Nov 15 '22 07:11

Barnabas Kecskes