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 для приложения, которое не повлияет на другие приложения на телефоне, или требуется оставить приложение для внесения изменений.