【问题标题】:Is String.format() on Android supposed to be timezone-aware?Android 上的 String.format() 应该是时区感知的吗?
【发布时间】:2025-11-26 23:20:03
【问题描述】:

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

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

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

我尝试使用另一种形式的String.format(),它需要一个额外的Locale 参数,并传递一个空语言环境(根据文档,这意味着“没有本地化”)——仍然相同。 (Locale 的文档根本没有提到时区,因此我怀疑语言环境是这里的问题。)

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

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

返回

1970-01-01 01:00:00

这是纪元的开始加上 CET 的时区偏移量(设备的时区)。因此,String.format() 明确添加了偏移量。

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

【问题讨论】:

    标签: java android timezone string-formatting


    【解决方案1】:

    String.format 表示默认时区的日期/时间。要使用 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 偏移。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 如果String.format() 完全不知道时区,我希望0L => 1970-01-01 00:00:00,但显然有一些有限的时区意识,因为它期望输入为UTC 格式输出为当地时间– 它缺少的是一种影响该处理的方法。我最终使用了DateFormat,因为它很容易获得并且非常简单。
      最近更新 更多