Date Format Change in App Store Receipts
After some sweat and tears we have found the reason for the installation failures in the Mac App Store: At some point in the last weeks, Apple has changed the format of the date values in its ASN.1 receipt files.
They used to look like “2020-10-03T07:12:34Z”. Now they added millisceonds like in “2020-10-03T07:12:34.567Z”. Apple’s specification only states that dates follow RFC 3339, which does not specify if there should be milliseconds or not.
[…]
To make it even harder, Apple still sends out receipts containing dates WITHOUT milliseconds if an app has been originally bought before October.
More on this: as far as I can tell the documented IAP dates are still returning dates that don’t have milliseconds. I don’t think there is a documented date field for Mac App Store receipts for the main app, as installed in the app binary.
These are the documented fields for local (on a Mac) receipt validation.
For server side receipt validation, there are host of other fields, including one that exposes the original purchase date in timestamp format.
The dates on the receipt documentation pages all mention they’re in ISO 8601, so you’d want to use that data formatter to read them instead of specifying an entirely manual, hand-crafted format string.
Hilariously, the documentation only promises that the date format will be “similar to the ISO 8601.”
A base ISO8601DateFormatter will parse the non-ms version only. To avoid this issue, devs would have to make two date parsers and try them one after another.
If anybody thinks ISO8601 datetime strings are a well-defined format, here’s the code in @MarsEdit that handles ISO8601 dates from various blogging platforms.
Previously:
- Receipt Validation and AirPlay 2
- App Store Certificate Checker Framework
- Receipt Validation in Swift
- Modern Receipt Validation
2 Comments RSS · Twitter
it doesn't help that Python, by default, spits out different date formats, depending on whether the fractional portion is zero or not.
From https://docs.python.org/3/library/datetime.html
datetime.isoformat(sep='T', timespec='auto')
Return a string representing the date and time in ISO 8601 format:
YYYY-MM-DDTHH:MM:SS.ffffff, if microsecond is not 0
YYYY-MM-DDTHH:MM:SS, if microsecond is 0
There also is a discussion on this topic in the Apple developer forum: https://developer.apple.com/forums/thread/663119?answerId=639779022#639779022