问题
What is the rationale behind Apple using Etc/GMT timezone when they return the receipt from the App Store for auto-renewable subscriptions.
What exactly is the Etc/GMT time zone? Does the Java SDK understand this time zone? Or do I have to use other third-party libraries like Joda-Time?
回答1:
Etc/GMT is not strictly the same thing as UTC or GMT. They represent the same instant in time only when the offset is 0. In all other cases, they are quite different.
Apple explains the designation here.
A quote directly from the link gives an example:
We use POSIX-style signs in the Zone names and the output abbreviations, even though this is the opposite of what many people expect. POSIX has positive signs west of Greenwich, but many people expect positive signs east of Greenwich. For example, TZ='Etc/GMT+4' uses the abbreviation "GMT+4" and corresponds to 4 hours behind UTC (i.e. west of Greenwich) even though many people would expect it to mean 4 hours ahead of UTC (i.e. east of Greenwich).
回答2:
Etc/GMT
is just a standard way of saying UTC
, GMT
, GMT0
or GMT+00:00
.
The Java JDK understands all of the formats. You can easily see this in action by doing the following:
import java.util.TimeZone;
public class Playground {
public static void main(String... args) {
for (String s : TimeZone.getAvailableIDs()) {
System.out.println(s);
}
}
}
This will print out all the different TimeZone
formats that your Java JDK can parse:
...
Etc/GMT
Etc/GMT+0
Etc/GMT-0
Etc/GMT0
Etc/Greenwich
Etc/UCT
Etc/UTC
Etc/Universal
...
回答3:
Offset versus zone
Understand:
- An offset-from-UTC is simply a number of hours-minutes-seconds, ahead of the baseline of UTC, or behind UTC.
- A time zone is much more. A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region.
Positive versus negative numbering
Different protocols in various industries have varied in their numbering, with some considering offsets ahead of UTC to be positive numbers while others used negative. Symmetrically, some considered offsets behind UTC to be negative while others used positive.
In most modern protocols I’ve seen, such as the ISO 8601, offsets ahead of UTC (towards the east) are positive, while offsets behind UTC (towards the west) are negative. So the offsets used by zones in the Americas have negative numbers such as America/Los_Angeles
having an offset of -07:00
or -08:00
nowadays (varies during the year because of Daylight Saving Time (DST)).
I suggest you learn to think of this manner (right of UTC is positive, left of UTC is negative) as mainstream, and the opposite as a minor annoying variation.
Time zone names are generally in the format Continent/Region
, such as America/Edmonton
, Europe/Paris
, Africa/Tunis
, Asia/Kolkata
, and Pacific/Auckland
. See this list on Wikipedia (may not be up-to-date). There are some exceptions. The Etc/GMT…
names carry the opposite plus/minus convention:
Etc/GMT+1
=-01:00
offset = One hour behind UTCEtc/GMT+12
=-12:00
offset = Twelve hours behind UTC
…and…
Etc/GMT-1
=+01:00
offset = One hour ahead of UTCEtc/GMT-12
=+12:00
offset = Twelve hours ahead of UTC
Confusing? Welcome to the wacky world of date-time handling. It only gets weirder from here.
Key points:
- Understand the meaning and intentions of those people publishing data. Never assume the meaning of an input string.
- Use java.time classes only for all your date-time work. Never use the terrible legacy classes
java.util.Date
,Calendar
,SimpleDateFormat
, and such.
Fortunately the java.time classes can help you through this muddle. See the correct Answer by Ole V.V. using the ZoneId
class.
Your questions
rationale behind Apple using Etc/GMT timezone
They mean an offset of zero, UTC itself. The string Etc/GMT
is one canonical label for an offset-from-UTC of zero hours-minutes-seconds.
The letter Z
(pronounced “Zulu”) seen commonly at the end of date-time strings means the same thing, an offset of zero.
What exactly is the Etc/GMT time zone?
The string Etc/GMT
is a name for a time zone which has had only one offset-from-UTC ever, an offset of zero hours-minutes-seconds.
Most other time zones such as Europe/Berlin
or Africa/Casablanca
have varied in their offset over history. For example, in that Africa/Casablanca zone in Morocco, the politicians have decided last year that rather than switching an hour twice a year for standard time & DST, they will now stay permanently on DST year-round. I say “permanently” with a chuckle, as that really means “until the politicians change their mind again”. Politicians around the world have shown a penchant for redefining their time zones with surprising frequency.
Does the Java SDK understand this time zone?
Yes. See the Answer by Ole V.V.: ZoneId.of( "Etc/GMT" )
Or do I have to use other third-party libraries like Joda-Time?
FYI, the Joda-Time project is now in maintenance mode, advising migration to the java.time classes. See Tutorial by Oracle.
You should be using java.time classes for all your date-time handling.
回答4:
When conveying a point in time across time zones it is a recommended standard to use either UTC or GMT (the two are roughly equivalent, for most purposes we don’t distinguish). It appears that Apple does exactly this.
The JDK understands Etc/GMT
just fine.
ZoneId etcGmt = ZoneId.of("Etc/GMT");
JDK uses the tz database (formerly known as the Olson database; link at the bottom). The list of time zone names in the database are in the other link at the bottom. Etc/GMT
is listed there. You will notice that it is given as the canonical name for GMT (there are also some aliases, some current and some deprecated).
As an aside, my code line of course uses ZoneId
from java.time, the modern Java date and time API. This is the JDK class that you will want to use (there is also an old and poorly designed class for time zones that you don’t want to use).
I don’t think you meant to ask, but for anyone interested: JDK also understands Etc/GMT+0
, Etc/GMT+1
, Etc/GMT0
, Etc/GMT-0
, Etc/GMT-1
, etc. (no pun intended) since they are in the database too. And it correctly handles the reversed sign mentioned in the quote in the accepted answer by David Peden.
Links
- Wikipedia article: tz database
- List of tz database time zones
- Documentation of ZoneId
回答5:
I suggest you to use a Java library for App Store receipts and stop thinking about the date format.
Add the artifact (by.dev.madhead.utils.appstore_receipts_validator:model:2.0.0).
Use any HTTP client to call the App Store and get the response back (here I use Ktor):
suspend fun verify(receipt: String, password: String): VerifyReceiptResponse {
val rawResponse = client.post<String> {
url("https://buy.itunes.apple.com/verifyReceipt")
contentType(ContentType.Application.Json)
accept(ContentType.Application.Json)
body = VerifyReceiptRequest(
receipt,
password,
true
)
}
}
Parse the response with Jackson:
val response = objectMapper.readValue(rawResponse)
Now you can use plain old Java API to work with the response.
来源:https://stackoverflow.com/questions/7303580/understanding-the-etc-gmt-time-zone