Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto-renewable subscription receipt date format

I'm struggling to figure out the formatting for the following date:

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

This date is returned from Apple's receipt validation service and I need to turn it into a NSDate for some comparison operations. The real trouble is related to the timezone.

Here's some code I've already written:

        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];

I've tried all combinations of 'v's and 'Z's that I can think of. Any insight?

like image 604
Hyperbole Avatar asked May 31 '11 20:05

Hyperbole


2 Answers

By looking at the date format documentation I got the correct format, is works well for me:

        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"]];

No need to set the time zone on the formatter since it's embedded in the string.
Manipulating the date string to parse it is not a good idea.

Source: http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns

like image 51
Yariv Nissim Avatar answered Oct 17 '22 19:10

Yariv Nissim


After doing some more research, the code I'm using here works, but is suspect;

   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];

I don't like the assumptions I am making about the incoming date string and so I am assuming this code may break for other stores (I'm testing against the UK one). So although this kind of works for my own situation, I'd really like to see a more robust solution that actually parses the timezone string correctly as per the original question.

I can't quite believe Apple have used a deprecated timezone (all the Etc/* ones are officially deprecated) in these important date strings!

EDIT:

I note you are using

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

This is not actually a string according to the documentation it should be "The expiration date of the subscription receipt, expressed as the number of milliseconds since January 1, 1970, 00:00:00 GMT"

However the question is still valid as you have to use the purchase_date field when working with restored subscriptions and this field is in the text format you have described.

like image 28
Roger Avatar answered Oct 17 '22 19:10

Roger