简体   繁体   中英

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

Sometimes my code is returning an am or pm 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 am450

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 am (which is expected) but others are. WHY?

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, eg “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, eg “17:00″.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM