java - 简单日期格式 mm :ss format - minutes get padded with a 3

标签 java android simpledateformat

我有一个最奇怪的问题 - 在我们的应用程序中,在一个地方我们使用 SimpleDateFormat 显示了一个用 mm:ss 格式化的时间。问题是我们在美国有一个客户提示他们将 5 分钟的格式设置为 35:00。我缩小了使用与我正在测试的相同值调用 SimpleDateFormat.format 的范围,但他们正在用 3 而不是 0 填充分钟。

问题是我无法重现该问题,他们告诉我他们已在 4 种不同的设备上进行了测试:

  • OPPO X9076 (Android 5.0)
  • 小米米A1(Android 8.1.0)
  • 三星SM-T715Y(Android 7.0)
  • 华为BLA-L29(安卓8.0)

我也在测试小米 Mi A1(和其他一些),但我尝试的时间还可以。

这是时间的格式:

SimpleDateFormat timeFormatter = new SimpleDateFormat("mm:ss", Locale.getDefault());
timeFormatter.format(new Date(5*60*1000));

有人见过这样的东西吗?

最佳答案

这是一个时区问题。或者更准确地说,是将 SimpleDateFormat 用于不适合它的用途的问题。 您可以通过以下方式重现:

    TimeZone.setDefault(TimeZone.getTimeZone("America/St_Johns"));
    SimpleDateFormat timeFormatter = new SimpleDateFormat("mm:ss", Locale.getDefault());
    System.out.println(timeFormatter.format(new Date(5*60*1000)));

这段代码的输出是:

35:00

解释: new Date(5*60*1000) 生成纪元后 5 分钟的日期时间,即 1970 年 1 月 1 日 00:05:00 UTC。此时与其他任何时间一样,世界上不同的地区有不同的时间。但是,大多数时区与 UTC 有整数小时的偏移量。所以时间将是整点过后 5 分钟,您的格式化程序会将其打印为 05:00。这就是为什么你之前没有注意到这个问题。例如,在柏林是 01:05:00,在纽约是前一天晚上的 19:05:00。但是,也有一些时区与 UTC 的偏移量不是整数小时。例如,亚洲/加尔各答是+05:30,亚洲/加德满都是+05:45。在这样的时区,时间不会是整点过5分钟,你会得到和你看到的一样意想不到的结果。

建议的解决方案包括:

  • 使用 TimeUnit 将秒转换为分钟和秒,使用 String.format 将它们分别格式化为两位数。
  • 如果您想要一个好的解决方案并且您可以接受在维护模式下对旧库的外部依赖,请查看 Joda-Time 的 PeriodFormatter

下面是使用 TimeUnit 计算要按照第一个项目符号中的建议格式化的部分的示例:

    long totalSeconds = TimeUnit.MINUTES.toSeconds(5); // 300

    long minutes = TimeUnit.SECONDS.toMinutes(totalSeconds);
    long secondsPart = totalSeconds - TimeUnit.MINUTES.toSeconds(minutes);
    String formattedDuration = String.format("%02d:%02d", minutes, secondsPart);
    System.out.println("Formatted duration: " + formattedDuration);

输出:

Formatted duration: 05:00

我不建议使用的丑陋技巧是将格式化程序的时区设置为 UTC。

我已经在评论中链接到的问题中有更多灵感。在撰写本文时,它有 20 个答案。我在底部重复链接。

顺便说一下,即使是格式化和解析日期和时间,您也可以考虑不使用 SimpleDateFormat。众所周知,它很麻烦,而且早已过时。而是将 ThreeTenABP 添加到您的 Android 项目,以便使用现代 Java 日期和时间 API java.time。与它一起工作要好得多。

链接

关于java - 简单日期格式 mm :ss format - minutes get padded with a 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53221986/

相关文章:

java - 打包 Java 控制台应用程序的最快方法

java - 添加用户名到审计表

android - Nexus 6 前置摄像头倒置

android - 在 Android ActionBar 选项卡上的选项卡内添加 FragmentActivity。

Java SimpleDateFormat 在 Date 对象中返回错误值

java - 当 "equality"暗示 "order doesn' t 重要时,如何编写传递比较器”?

Android 单行文本提示

java - 将日期格式从 yyyy-mm-dd 更改为 yyyy/mm/dd

java - 比较 Java 错误中的两个字符串时间

java - 有没有办法让 Jetty 在 Java 代码中使用 SSL