Android 上的 String.format() 应该是时区感知的吗?

Is String.format() on Android supposed to be timezone-aware?

我使用以下代码将 GPS 位置的时间戳转换为人类可读的形式:

String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", location.getTime())

根据 the docs,GPS 位置时间戳应采用 UTC。但是,我得到的字符串是当地时间(在两个不同的设备上测试过)。

我试过使用另一种形式的 String.format(),它需要一个额外的 Locale 参数,并向它传递一个空语言环境(根据文档,这意味着 "no localization" ) - 还是一样。 (而且 Locale 的文档根本没有提到时区,因此我怀疑语言环境是这里的问题。)

我的另一个怀疑是 GPS 堆栈可能不按规定运行,提供本地时间而不是 UTC。我用

测试了这个
String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", (long) 0)

哪个returns

1970-01-01 01:00:00

这是纪元的开始加上 CET 的时区偏移量(设备的时区)。因此偏移量显然增加了 String.format().

String.format() 是否应该进行任何时区转换?我如何影响此行为,即选择要转换到哪个时区或完全禁止转换?

String.format 不支持时区。使用 Joda 时间库。库中的 datetime zone 和 datetimeformat 类 可让您格式化可识别时区的日期时间。你会在网上获得很多关于如何做到这一点的例子,所以我在这里不做详细介绍。 :)

String.format 表示默认时区中的 date/time。要以 UTC 格式设置格式,请改用 SimpleDateFormat,您可以在其中明确设置要使用的时区:

String formatInUtc(long millis) {
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
    df.setTimeZone(TimeZone.getTimeZone("UTC"));
    return df.format(new Date(millis));
}

E. g.:

System.out.println(formatInUtc(0L)); //  1970-01-01 00:00:00

顺便说一句,区域设置和时区是正交的:区域设置决定了文本表示的各个方面(数字、符号、分隔符、语言),而时区决定了时钟与 UTC 的偏移方式。