可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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:@""];
回答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.
回答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];
回答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.
回答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.
回答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!
回答6:
For those finding this question who want to use NSDateFormatter to parse 24-hour time and are hitting this bug, using NSDateComponents to parse dates and times which have a known format sidesteps this issue:
NSString *dateStr = @"2010-07-05";
NSString *timeStr = @"13:30";
NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = [[dateStr substringToIndex:4] intValue];
components.month = [[dateStr substringWithRange:NSMakeRange(5, 2)] intValue];
components.day = [[dateStr substringFromIndex:8] intValue];
components.hour = [[timeStr substringToIndex:2] intValue];
components.minute = [[timeStr substringFromIndex:3] intValue];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [calendar dateFromComponents:components];
[components release];
[calendar release];
回答7:
This should also work (I am seeing some bizzare results though).
-(NSString*)lowLevTime:(NSString*)stringFormat {
char buffer[50];
const char *format = [stringFormat UTF8String];
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, sizeof(buffer), format, timeinfo);
return [NSString stringWithCString:buffer encoding:NSASCIIStringEncoding];
}
回答8:
Short answer: try [dateFormatter setDateFormat:@"yyyyMMddhhmmss"];
for 12 hour format (note the lowercase hh
).
It's been a frustrating topic because so many websites indicate to use HH
for hours (including the official Apple documentation), but that sets it to 24 hour format, whereas hh
uses 12 hour format. See http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns for more details.
As a bonus, note that you can also use KK
or kk
for hour of the day format, which will likely be off by one.
Update:
I was recently looking at NSLocale (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html) and it would seem that you can use autoupdatingCurrentLocale to apply changes made from within the app to the Locale. The upshot of this is that even if the phone is set to use a 24 hour clock (like when you switched to France), you can make a 12/24 toggle for the app that won't impact any other apps on the phone, or require you to leave the app to make the change.