30

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
royalghost
  • 2,773
  • 5
  • 23
  • 29
  • Do you have a reason to assume it's not just a strange way of saying UTC? – hmakholm left over Monica Sep 05 '11 at 03:13
  • I guess so, but why are they using it? Just to make it look complex! – royalghost Sep 05 '11 at 03:29
  • They're probably forced for some reason to work relative to a timezone database that organizes locales in the usual Continent/City structure and uses "Etc" as an escape for "things that don't follow that structure". – hmakholm left over Monica Sep 05 '11 at 03:32
  • FYI, the [*Joda-Time*](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), advising migration to the [*java.time*](http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jul 25 '19 at 03:11

5 Answers5

32

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).

David Peden
  • 17,596
  • 6
  • 52
  • 72
  • 8
    FYI - that's just apple's copy of the [tz database](http://iana.org/time-zones). Those comments are [in the database itself](https://github.com/eggert/tz/blob/master/etcetera), not coming from Apple. – Matt Johnson-Pint Jul 10 '15 at 19:13
17

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 UTC
  • Etc/GMT+12 = -12:00 offset = Twelve hours behind UTC

…and…

  • Etc/GMT-1 = +01:00 offset = One hour ahead of UTC
  • Etc/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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
8

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
...

Nico Huysamen
  • 10,217
  • 9
  • 62
  • 88
  • 1
    Exactly! It will say that it can parse it, but when I tried it throws ParseException. Although, I found the workaround for now. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); sdf.setTimeZone(TimeZone.getTimeZone("Etc/GMT")); try { System.out.println( sdf.parse("2011-09-02 10:26:35 Etc/GMT") ); } catch (ParseException e) { e.printStackTrace(); } – royalghost Sep 05 '11 at 10:04
  • 1
    See my answer for the correct way to interpret the timezone designator and the rationale. – David Peden Jan 11 '14 at 04:01
  • This answer is Etc/Correct – RoundTower Sep 08 '14 at 13:49
  • 2
    This Answer is now obsolete. The `TimeZone` class is now legacy, replaced by `ZoneId` and `ZoneOffset`. See JSR 310. – Basil Bourque Jul 25 '19 at 02:47
1

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

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

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.

madhead
  • 31,729
  • 16
  • 153
  • 201