NSDateFormatter, я делаю что-то неправильно или это ошибка?
-
02-07-2019 - |
Вопрос
Я пытаюсь распечатать дату в определенном формате:
NSDate *today = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
NSString *dateStr = [dateFormatter stringFromDate:today];
Если iPhone настроен на 24-часовое время, это работает нормально, если, с другой стороны, пользователь установил его на 24-часовое время, затем возвращается к AM / PM (он работает нормально, пока вы не переключите этот параметр), затем он добавляет AM / PM в конце, хотя я об этом не просил:
20080927030337 PM
Я делаю что-то неправильно или это ошибка с прошивкой 2.1?
Правка 1:Сделал описание более четким
Правка 2 обходной путь:Оказывается, это ошибка, чтобы исправить ее, я установил символы AM и PM равными "".:
[dateFormatter setAMSymbol:@""];
[dateFormatter setPMSymbol:@""];
Решение
Используя код, который вы разместили как на симуляторе, так и на телефоне с прошивкой 2.1 и 24-часовым временем, установленным в положение выкл, я никогда не добавлял AM / PM к dateStr, когда я делаю:
NSLog(@"%@", dateStr);
Делаете ли вы что-нибудь еще с dateStr, чего вы здесь не публиковали?Как вы проверяете это значение?
Последующие действия
Попробуйте включить, а затем выключить настройку am / pm.У меня тоже не было проблемы, пока я этого не сделал.Я распечатываю его таким же образом, как и вы.
Хорошо, я тоже вижу это, когда делаю это.Должно быть, это ошибка.Я рекомендую вам отправьте отчет об ошибке а пока просто проверьте и отфильтруйте нежелательные символы.
Другие советы
Причиной такого поведения является Locale, он устанавливает правильный Locale.
Установите локальный адрес вашего Nsdateформатер Для en_US_POSIX ( ru_US_POSIX ) я это исправлю.Это работает как для 24-часового, так и для 12-часового формата.
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.
От яблочный док
Попробуй это,
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];
Вот объяснение ошибки iPhone SDK (также все еще присутствует в 3.1 beta SDK)
Во-первых, немного о пользовательском интерфейсе iPhone.Когда пользователи iPhone меняют формат своего региона, скажем, с ”Соединенные Штаты" на “Франция“, настройка ”24-часовое время" пользователей автоматически переключается в режим, который наиболее распространен в этом регионе.Во Франции это установило бы 24-часовое время на “ВКЛЮЧЕНО”, а в США это установило бы его на “ВЫКЛЮЧЕНО”.Затем пользователь может вручную изменить эти настройки, вот где проблема начинается.
Проблема возникает из-за того, что NSDateFormatter каким-то образом “застревает” в 12 или 24-часовом режиме времени, который пользователь выбрал вручную.Таким образом, если французский пользователь вручную выбирает 12-часовой режим, а приложение запрашивает NSDateFormatter для вывода времени в 24-часовом формате “HHmm”, на самом деле он будет получать время в 12-часовом формате, например“01:00 вечера”, как если бы приложение вместо этого запросило ”hhmm aa".Обратное произошло бы, если бы американский пользователь вручную выбрал 24-часовой режим:при выводе времени в 12-часовом формате “hhmm aa” фактически будет получено вместо этого ваше время в 24-часовом формате, например“17:00″.
Более подробную информацию и возможное обходное решение можно найти здесь Блог.
Установка locale в программе форматирования даты на en_US устраняет проблему для меня:
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];
Я не уверен, нужно ли также добавлять календарь, но это работает хорошо.
Я думаю , что это и есть решение .
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!
Для тех, кто находит этот вопрос, кто хочет использовать NSDateFormatter для анализа 24-часового времени и сталкивается с этой ошибкой, использование NSDateComponents для анализа дат и времени, которые имеют известный формат, устраняет эту проблему:
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];
Это также должно сработать (хотя я вижу некоторые причудливые результаты).
-(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];
}
Краткий ответ:попробуй [dateFormatter setDateFormat:@"yyyyMMddhhmmss"];
для 12-часового формата (обратите внимание на нижний регистр hh
).
Это была неприятная тема, потому что так много веб-сайтов указывают на использование HH
для часов (включая официальную документацию Apple), но это переводит его в 24-часовой формат, тогда как hh
использует 12-часовой формат.Видишь http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns для получения более подробной информации.
В качестве бонуса обратите внимание, что вы также можете использовать KK
или kk
для формата "час дня", который, скорее всего, будет отключен к часу дня.
Обновить:Недавно я просматривал NSLocale (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html) и, казалось бы, вы можете использовать autoupdatingCurrentLocale для применения изменений, внесенных внутри приложения, к языковому стандарту.Результатом этого является то, что даже если телефон настроен на использование 24-часовых часов (например, когда вы переключились на Францию), вы можете переключить приложение на 12/24, что не повлияет на другие приложения на телефоне или потребует от вас выхода из приложения для внесения изменений.