NSDateFormatter, я делаю что-то неправильно или это ошибка?
Я пытаюсь распечатать дату в определенном формате:
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:@""];
Ответы
Ответ 1
Используя код, который вы отправили на симуляторе и на телефоне с прошивкой 2.1 и 24-часовым временем, отключенным, у меня никогда не было AM/PM, добавленного к dateStr, когда я это делаю:
NSLog(@"%@", dateStr);
Вы делаете что-нибудь еще с dateStr, которое вы не публиковали здесь? Как вы проверяете значение?
Последующие действия
Попробуйте включить настройку am/pm, а затем выключить. У меня тоже не было проблемы, пока я это не сделал. Я печатаю его так же, как и вы.
Хорошо, я вижу это, когда я это делаю. Это должно быть ошибкой. Я рекомендую вам создать отчет об ошибке и просто проверить и отфильтровать нежелательные символы за это время.
Ответ 2
Причиной такого поведения является Locale, установить правильный локаль, установить локальный NSDateFormatter на 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.
Из apple doc
Попробуйте это,
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
Здесь объяснение ошибки iPhone SDK (также еще есть в 3.1 beta SDK)
Во-первых, небольшой фон в пользовательском интерфейсе iPhone. Когда iPhone пользователи меняют свой региональный формат между, скажем, "США" и "Франция", настройка "24-часовое время" пользователей автоматически переключается к режиму, который наиболее распространен в этом регионе. Во Франции это установит 24-часовое время на "ON", а в США - на "OFF". Затем пользователи могут вручную переопределить этот параметр, и это где начинается проблема.
Проблема возникает из-за того, что NSDateFormatter "застревает" в 12 или 24-часовой режим, который пользователь выбрал вручную. Поэтому, если Французский пользователь вручную выбирает 12-часовой режим, а приложение запросил NSDateFormatter для вывода времени с 24-часовым форматом "HHmm", он фактически получит время в 12-часовом формате, например. "01:00 PM", как если бы приложение вместо этого попросило "hhmm aa". Обратное произойдет, если пользователь США вручную выберет 24-часовой режим: вывод времени с 12-часовым форматом "hhmm aa" фактически вы используете время в 24-часовом формате, например, "17:00".
Более подробную информацию и возможное обходное решение можно найти на этом блоге.
Ответ 4
Настройка языка для форматирования даты в 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];
Я не уверен, что добавление календаря также необходимо, но это хорошо работает.
Ответ 5
Я думаю, что это решение.
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
Для тех, кто находит этот вопрос, который хочет использовать 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];
Ответ 7
Это также должно работать (я вижу некоторые результаты bizzare).
-(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
Короткий ответ: попробуйте [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 для приложения, которое не повлияет на другие приложения на телефоне, или требуется оставить приложение для внесения изменений.