NSDateFormatter dateFromString и iPhone в путанице 24-часового формата

У меня проблема. Я получаю входящие строки времени в 12-часовом формате и превращаю их в объекты NSDate. Когда iPhone в 12-часовом формате, нет проблем. Но когда это в 24-часовом формате, все идет не так. Вот пример кода для демонстрации:

NSString *theTime = @"3:19 PM";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"h:mm a"]; // "3:19 PM"
NSDate *date = [formatter dateFromString:theTime];
NSString *theString = [formatter stringFromDate:date];

В 24-часовом режиме date — это 1970-01-01 03:19:00, а theString — «3:19» — НЕПРАВИЛЬНО.

В 12-часовом режиме дата — 1970-01-01 15:19:00, а theString — «15:19» — ПРАВИЛЬНО.

Итак... вопрос 1: почему 24-часовая настройка устройства переопределяет мою настройку форматирования даты?

и, что более важно, вопрос 2: как правильно преобразовать 12-часовое время в 24-часовое?

У меня уже есть код, чтобы определить, находится ли телефон в 24-часовом режиме, но кроме копания в строке и замены 3 на 15, похоже, нет простого способа сделать это.


person Silromen    schedule 01.02.2010    source источник


Ответы (5)


Не уверен, что вам это все еще нужно, но у меня была аналогичная проблема, которая была решена путем установки локали для форматирования даты. То есть, если вы хотите принудительно перевести его в 12-часовой режим, независимо от настройки режима 24/12, установленного пользователем, вы должны установить локаль en_US_POSIX.

person SVD    schedule 27.05.2010
comment
Этот ответ пришел спустя много времени после того, как я выбрал другой маршрут, но он звучит разумно, и кто-то другой подтвердил его, поэтому я отмечу его как ответ. - person Silromen; 14.02.2011
comment
Не столь очевидный вывод: пусть локаль системы подойдет для нормального [[NSDateFormatter alloc] init]-созданного формата даты. Используйте этот модуль форматирования для любых строк, которые вы показываете пользователю. Если вы хотите взять строку из источника, который всегда имеет 12- или 24-часовое время (скажем, константу приложения или сервер), используйте .locale = [[NSLocale alloc] initWithLocaleIdentifier:@“en_US_POSIX"] на другом форматере, чтобы убедиться, что они не обрабатываются неправильно. Просто помните, что средства форматирования даты контролируют 12/24-часовое выражение времени, а NSDate — нет, и все будет хорошо. - person cbowns; 25.04.2012

Причиной такого поведения является локаль, установите правильную локаль

    NSString *strAgendaDate = @"01/17/2012 12:00 AM";
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    [dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];

    [dateFormatter setDateFormat:AgendaDateFormatForMeeting];
    NSDate *meetingDate = [dateFormatter dateFromString:aStrDate];
    [dateFormatter setDateFormat:AgendaDateRepresentation];
    strAgendaDate = [dateFormatter stringFromDate:meetingDate];

Работает как в 24-часовом, так и в 12-часовом формате.

person Meet    schedule 12.09.2012
comment
спасибо @Meet, это безумие, как одна строка кода может все изменить :) - person DrPatience; 05.08.2015

Я считаю, что @"h:mm a" должно быть @"HH:mm a".

Если вы используете pre-build dateformatter в какао, обо всем позаботятся за вас.

NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease];
[timeFormatter setTimeStyle:NSDateFormatterShortStyle];
[timeFormatter setDateStyle:NSDateFormatterNoStyle];

NSDateFormatterShortStyle и NSDateFormatterNoStyle бывают разных видов. Их использование гарантирует, что вы соблюдаете настройки, выбранные пользователем для даты и времени.

О преобразовании часов в 12-14 часов заботится SDK, если у вас есть модель или какой-либо объект значения для хранения ваших дат, попробуйте сохранить их как NSDate. Таким образом, вы можете форматировать их только тогда, когда вам нужно их отобразить. Сохранение дат в виде строк может вызвать множество проблем, когда вы, возможно, анализируете их из xml, где GMT ​​указывается отдельно, или пытаетесь добавить и вычесть NSTimeIntervals.

person RickiG    schedule 01.02.2010
comment
Спасибо. Я попробовал этот код: NSString *theTime = @15:19; NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease]; [timeFormatter setTimeStyle:NSDateFormatterShortStyle]; [timeFormatter setDateStyle:NSDateFormatterNoStyle]; NSDate *date = [timeFormatter dateFromString:theTime]; NSString *theString = [timeFormatter stringFromDate:date]; И дата приходит ноль. Я столкнулся с этим ранее, когда пробовал этот маршрут, и он не работает. Очень расстраивает. - person Silromen; 01.02.2010

Я изменил с @"чч:мм:сс" на @"ЧЧ:мм:сс", а стиль времени был изменен с "13:03. strong>" на "13:03". Надеюсь, что это поможет вам.

person Vladimir    schedule 28.01.2014

Хорошо, я оставил комментарий, но он сжал весь код, поэтому мне придется «ответить» на мой вопрос комментарием:

Спасибо. Я дал ему вихрь с этим кодом:

NSString *theTime = @"3:19 PM"; 
NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] init] autorelease];       
[timeFormatter setTimeStyle:NSDateFormatterShortStyle]; 
[timeFormatter setDateStyle:NSDateFormatterNoStyle]; 
NSDate *date = [timeFormatter dateFromString:theTime]; 
NSString *theString = [timeFormatter stringFromDate:date]; 

И дата приходит ноль. Я столкнулся с этим ранее, когда пробовал этот маршрут, и он не работает. Очень расстраивает.

person Silromen    schedule 01.02.2010
comment
Здравствуй Силомен. Этот подход предназначен только для отображения даты и времени. Чтобы построить даты из строк, вам нужно применить правильный формат. Как здесь: [formatter setDateFormat:@h:mm a]; // 15:19 Но обратите внимание на HH вместо hh. - person RickiG; 01.02.2010
comment
Спасибо за ответ, но это просто не работает. На iPhone в 24-часовом режиме 15:54 по-прежнему отображается как объект даты 03:54:00, а в симуляторе (с часами моего компьютера в 24-часовом режиме) было хуже: 12:54:00. - person Silromen; 01.02.2010