Подтвердить что ты не робот

Формат даты получения подписки на автоматическое возобновление

Я пытаюсь выяснить форматирование на следующую дату:

2011-05-24 19:02:32 Etc/GMT

Эта дата возвращается из службы проверки чеков Apple, и мне нужно превратить ее в NSDate для некоторых операций сравнения. Настоящая проблема связана с часовым поясом.

Вот код, который я уже написал:

        NSDictionary *receiptData = [info valueForKey:@"expires_date"];

        NSDateFormatter *f = [[NSDateFormatter alloc] init];

        [f setLocale:[NSLocale currentLocale]];
        [f setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
        [f setDateFormat:@"yyyy-MM-dd HH:mm:ss vvvv"];

        NSLog(@"%@", [f stringFromDate:[NSDate date]]);

        NSDate *subPurchaseDate = [f dateFromString:[receiptData valueForKey:@"original_purchase_date"]];

        [f release];

Я пробовал все комбинации "v" и "Z", о которых я могу думать. Любое понимание?

4b9b3361

Ответ 1

Изучая документацию формата даты, я получил правильный формат, хорошо работает для меня:

        NSDateFormatter * formatter = [NSDateFormatter new];
        formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss VV";

        NSDate * purchaseDate = [formatter dateFromString:latestTransaction[@"original_purchase_date"]];
        NSDate * expirationDate = [formatter dateFromString:latestTransaction[@"expires_date"]];

Не нужно устанавливать часовой пояс в форматировании, так как он встроен в строку.
Манипулирование строки даты для синтаксического анализа не является хорошей идеей.

Источник: http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns

Ответ 2

Проведя еще несколько исследований, код, который я использую здесь, работает, но подозрительный;

   NSString *purchaseDateString = [@"2011-05-24 19:02:32 Etc/GMT" stringByReplacingOccurrencesOfString:@" Etc/GMT" withString:@""];
   NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
   NSLocale *POSIXLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];
   [formatter setLocale:POSIXLocale];
   [formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
   [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

   NSDate *purchaseDate = [formatter dateFromString:purchaseDateString];

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

Я не могу поверить, что Apple использовала устаревший часовой пояс (все Etc/* официально устарели) в этих важных строках даты!

EDIT:

Заметьте, что вы используете

NSDictionary *receiptData = [info valueForKey:@"expires_date"];

На самом деле это не строка в соответствии с документацией, она должна быть "Дата истечения срока действия подписки, выраженная в миллисекундах с 1 января 1970 года, 00:00:00 GMT"

Однако вопрос остается в силе, поскольку вы должны использовать поле purchase_date при работе с восстановленными подписками, и это поле находится в текстовом формате, который вы описали.

Ответ 3

Это то, что я делаю на Swift 3, чтобы преобразовать дату с даты автоматического возобновления из квитанции.

let expirationDate = "2017-08-16 23:10:35 Etc/GMT"
let receiptDateFormat = "yyyy-MM-dd HH:mm:ss VV"
let theDateFormat = DateFormatter.Style.medium
let theTimeFormat = DateFormatter.Style.medium
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = receiptDateFormat
let firstDate = dateFormatter.date(from: stringDate)
dateFormatter.dateStyle = theDateFormat
dateFormatter.timeStyle = theTimeFormat

let result = dateFormatter.string(from: firstDate!)