Дата преобразования формата гггг-мм-dd'T'H: mm:ss.СНО


У меня есть несколько объектов NSDate, которые содержат значения, соответствующие этому формату yyy-MM-dd'T'HH:mm:ss.SSS

Когда я пытаюсь преобразовать в другой формат, такой как MMM dd, yyyy HH:mm, форматер всегда возвращает nil.

Однако, если я жестко закодирую строковое значение , которое я получаю через объект NSDate, оно преобразуется в новый формат без проблем.

Я заполняю свой объект NSDate в модели с помощью метода setValue:forKey:, и я чувствую, что проблема здесь, Где Библиотека JSON передает строковое значение. Тем не менее, отладка показывает, что NSDate has содержит значение, возвращаемое через JSON.

Есть идеи, чем вызвано это странное поведение?

Это мой код преобразования:

NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
NSString *createdDateStr = [format stringFromDate:modelObj.createdDate];
[format setDateFormat:@"MMM dd, yyyy HH:mm"];

NSDate *formattedDate = [format dateFromString:createdDateStr];
NSLog(@"========= REal Date %@",[format stringFromDate:formattedDate]);
3 3

3 ответа:

EDIT: перечитывая ваш вопрос, я думаю, что у вас есть концептуальное недоразумение помимо всего прочего:

У меня есть несколько объектов NSDate, которые содержат значения, соответствующие следующему формату

Насколько мне известно (я не программист Objective-C), объект NSDate ничего не знает о форматировании. Он просто представляет собой мгновение во времени. Он не знает, Был ли он проанализирован из текста или создан каким-то другим способом.

Это как и переменная int - переменная int не является десятичной или шестнадцатеричной, это просто число. Это когда вы форматируете и анализируете, что вы указываете это. Аналогично, вы используете NSDateFormatter для описания нужного вам формата в точке синтаксического анализа и форматирования.


В настоящее время у вас есть только один NSDateFormatter - вы устанавливаете формат в "yyyy-MM-dd'T'HH:mm:ss.SSS", а затемсбрасываете его перед вызовом dateFromString. Фрагмент кода, который вы дали форматирует modelObj.createdDate в формат ISO-8601, но затем пытается разберем его, используя формат "МММ ДД, гггг чч: мм".

Я предлагаю вам иметь два отдельных объекта NSDateFormatter:

NSDateFormatter *isoFormat = [[NSDateFormatter alloc] init];
[isoFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
NSString *createdDateStr = [format stringFromDate:modelObj.createdDate];

NSDateFormatter *shortFormat = [[NSDateFormatter alloc] init];
[shortFormat setDateFormat:@"MMM dd, yyyy HH:mm"];

NSDate *parsedDate = [isoFormat dateFromString:createdDateStr];
NSLog(@"========= REal Date %@",[shortFormat stringFromDate:parsedDate]);

Обратите внимание, что я изменил вашу переменную formattedDate на parsedDate, так как это то, что это на самом деле - NSDate, который был создан путем синтаксического анализа текста.

Как было отмечено в комментариях, если вам на самом деле не нужно форматировать и анализировать таким образом, вы не должны. я включил весь ваш исходный код только для того, чтобы показать, как вы можете форматировать дату, а затем повторно использовать это с тем же NSDateFormatter. Вы получите тот же результат, просто:

NSDateFormatter *shortFormat = [[NSDateFormatter alloc] init];
[shortFormat setDateFormat:@"MMM dd, yyyy HH:mm"];    
NSLog(@"========= REal Date %@",[shortFormat stringFromDate:modelObj.createdDate]);

В общем, вам следует избегать ненужных преобразований. Преобразуйте из текста в более естественный тип данных (NSDate в этом случае, но то же самое относится к числам и т. д.) и используйте этот тип данных для максимально возможной части вашего кода, только преобразуя в текст в последний момент.

Проблема заключается в том, что вы создаете строку из даты с одним форматом, а затем пытаетесь преобразовать ее обратно в дату с другим форматом. Чтобы создать дату из строки, вы должны использовать тот же формат, который вы использовали для создания этой строки, иначе вы получите ноль. Если вам нужна отформатированная строка с другим форматом, то сначала создайте дату из строки с правильным форматом, а затем преобразуйте ее обратно в строку с нужным вам форматом. Вопрос заключается в приказе.

NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
NSString *createdDateStr = [format stringFromDate:modelObj.createdDate];


NSDate *formattedDate = [format dateFromString:createdDateStr];

[format setDateFormat:@"MMM dd, yyyy HH:mm"];
NSLog(@"========= REal Date %@",[format stringFromDate:formattedDate]);

Другой подход заключается в использовании различные форматтеры, такие как Jon Skeet, предлагают просто во избежание путаницы...

У тебя есть NSDate, modelObj.createdDate, и вы хотите отформатировать его как строку в определенном формате, MMM dd, yyyy HH:mm. Вам не нужно преобразовывать дату в строку, а затем обратно в другую NSDate, а затем снова в строку. Если вы используете один и тот же форматер для обеих операций, вы просто получите ту же дату, с которой начали.

Вам нужно только отформатировать дату один раз, чтобы ваш окончательный желаемый внешний вид:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"MMM dd, yyyy HH:mm"];
NSLog(@"========= REal Date %@",[format stringFromDate:modelObj.createdDate]);

Сам по себе NSDate не соответствует следующему формату. Оно имеет нет формат-это момент времени, смещение от исходной даты. Если Вы NSLog() его, он действительно отформатирует себя в удобочитаемую строку (возможно, используя форматер даты за кулисами), но это только одно представление, которое он выбирает.

Прямо сейчас вы получаете nil от второй операции форматирования, NSDate *formattedDate = [format dateFromString:createdDateStr]; потому что формат строки, которую вы передаете в форматер, должен точно соответствовать тому, что ожидает форматер. В данном случае это не так, потому что вы создали строку, используя формат yyyy-MM-dd'T'HH:mm:ss.SSS, но сказали форматеру ожидать MMM dd, yyyy HH:mm. Форматер, таким образом, не может разобрать строку и возвращает nil, чтобы указать на сбой.