Автообновляемый формат даты получения подписки - PullRequest
15 голосов
/ 01 июня 2011

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

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», о которых я могу подумать. Любое понимание?

Ответы [ 3 ]

15 голосов
/ 07 июня 2014

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

        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

4 голосов
/ 13 июня 2011

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

   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 по Гринвичу"

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

0 голосов
/ 18 августа 2017

Это то, что я делаю в 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!)
...