当苹果从App Store返回自动更新订阅的收据时,他们使用Etc/GMT时区的理由是什么?
Etc/GMT时区到底是什么?Java SDK理解这个时区吗?或者我必须使用其他第三方库,如Joda-Time?
Etc/GMT是不是与UTC或GMT严格相同的东西。只有当偏移量为0时,它们才表示时间上的同一瞬间。在所有其他情况下,它们是完全不同的。
苹果公司在这里解释了这个名称。
直接引用链接给出了一个例子:
我们在Zone名称和输出缩写中使用posix风格的符号,尽管这与许多人期望的相反。POSIX在格林威治以西有积极的迹象,但许多人期望格林尼治东部出现了积极的迹象。例如,TZ='Etc/GMT+4'使用缩写"GMT+4",比UTC晚4小时(即格林威治以西),尽管很多人认为它是平均比UTC早4小时(即格林威治以东)。
偏移量与区域
理解:
- 从UTC的偏移量是简单的小时-分钟-秒数,在UTC的基线之前,或在UTC之后。
- 一个时区是很多更多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。
正数与负数
不同行业的不同协议的编号各不相同,有些协议认为UTC 前面的偏移量是正数,而其他协议则使用负数。对称地,一些人认为在 UTC之后的偏移量是负的,而另一些人则使用正的。
在我所见过的大多数现代协议中,例如ISO 8601,在UTC之前(向东)的偏移量是正的,而在UTC之后(向西)的偏移量是负的。因此,美洲地区使用的偏移量为负数,例如America/Los_Angeles
现在的偏移量为-07:00
或-08:00
(由于夏令时(DST),每年都会有所不同)。
我建议你学会把这种方式(UTC的右边是正的,UTC的左边是负的)视为主流,而相反的是一个小的令人讨厌的变化。
时区名称一般采用Continent/Region
格式,如America/Edmonton
、Europe/Paris
、Africa/Tunis
、Asia/Kolkata
、Pacific/Auckland
等。请参阅维基百科上的这个列表(可能不是最新的)。也有一些例外。Etc/GMT…
名称采用相反的加减约定:
-
Etc/GMT+1
=-01:00
offset = 落后 UTC 1小时 -
Etc/GMT+12
=-12:00
offset = 落后 UTC 12小时
……
-
Etc/GMT-1
=+01:00
offset = UTC提前1小时 -
Etc/GMT-12
=+12:00
offset = UTC提前12小时
困惑吗?欢迎来到约会时间处理的古怪世界。从这里开始只会变得更奇怪。
重点:
- 了解那些发布数据的人的含义和意图。永远不要假定输入字符串的含义。 <
- 使用em> java。Time 类仅用于所有日期时间工作。永远不要使用可怕的遗留类
java.util.Date
、Calendar
、SimpleDateFormat
等。
幸运的是java。Time 类可以帮助您解决这个问题。请看Ole V.V.使用ZoneId
类给出的正确答案。
苹果使用Etc/GMT时区的理由
表示UTC本身的偏移量为0。字符串Etc/GMT
是表示从utc偏移量为0小时-分钟-秒的标准标签。
通常出现在日期时间字符串末尾的字母Z
(发音为"Zulu")表示相同的含义,偏移量为零。
Etc/GMT时区到底是什么?
字符串Etc/GMT
是一个时区的名称,该时区从utc到现在只有一个偏移量,偏移量为0小时-分钟-秒。
大多数其他时区,如Europe/Berlin
或Africa/Casablanca
,其偏移量随着历史的变化而变化。例如,在摩洛哥的Africa/Casablanca
地区,政客们去年决定,与其每年两次将一小时的时间转换为标准时间,不如将其改为标准时间。夏令时,他们现在将永久地保持全年的夏令时。我笑着说"永久",因为这实际上意味着"直到政客们再次改变主意"。世界各地的政治家都表现出了以惊人的频率重新定义时区的嗜好。
Java SDK理解这个时区吗?
是的。参见Ole V.V.: ZoneId.of( "Etc/GMT" )
或者我必须使用其他第三方库,如Joda-Time?
仅供参考,Joda-Time项目现在处于维护模式,建议迁移到java。时间类。
您应该使用java。Time 类用于所有日期时间处理。
Etc/GMT
只是UTC
, GMT
, GMT0
或GMT+00:00
的标准说法。
Java JDK理解所有的格式。通过执行以下操作,您可以很容易地看到这一点:
import java.util.TimeZone;
public class Playground {
public static void main(String... args) {
for (String s : TimeZone.getAvailableIDs()) {
System.out.println(s);
}
}
}
这将打印出Java JDK可以解析的所有不同的TimeZone
格式:
…等/GMT
等/GMT + 0
等/GMT-0
等/GMT0
等/格林威治
等/节点
等/UTC
等/通用
…
在跨时区传递时间点时,建议使用UTC或GMT(两者大致等效,对于大多数目的我们不区分)。看来苹果就是这么做的。
JDK可以很好地理解Etc/GMT
。
ZoneId etcGmt = ZoneId.of("Etc/GMT");
JDK使用tz数据库(以前称为Olson数据库;链接在底部)。数据库中的时区名称列表位于底部的另一个链接中。Etc/GMT
列在那里。您将注意到,它以的形式给出了GMT的规范名称(也有一些别名,一些是当前的,一些是废弃的)。
ZoneId
。time,现代Java日期和时间API。这是您想要使用的JDK类(还有一个您不想使用的旧的、设计不良的时区类)。
我不认为你想问,但是对于任何感兴趣的人:JDK也理解Etc/GMT+0
, Etc/GMT+1
, Etc/GMT0
, Etc/GMT-0
, Etc/GMT-1
等(没有双关语的意思),因为它们也在数据库中。它正确地处理了David Peden公认答案中引用的反号。
与
- 维基百科条目:tz数据库
- tz数据库时区列表
-
ZoneId
我建议你使用Java库来处理App Store收据,不要再考虑日期格式。
添加工件(by.dev.madhead.utils.appstore_receipts_validator:model:2.0.0
)
使用任何HTTP客户端调用App Store并获得响应返回(这里我使用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
)
}
}
用Jackson解析响应:
val response = objectMapper.readValue(rawResponse)
现在您可以使用普通的Java API来处理响应。