SimpleDateFormat mm:ss格式-分钟用3填充

时间:2018-11-09 08:13:49

标签: java android simpledateformat

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

问题是我无法重现该问题,他们告诉我他们已测试并在4种不同的设备上得到它:

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

我也在小米Mi A1(以及其他一些设备)上进行测试,但是尝试的时间还可以。

时间是这样格式化的:

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

有人看到过这样的东西吗?

1 个答案:

答案 0 :(得分:4)

这是时区问题。或者更确切地说,是误用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的偏移量为整个小时数。因此时间将是每小时的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);

输出:

  

格式化时间:05:00

我不建议您使用丑陋的方法,将格式化程序的时区设置为UTC。

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

顺便说一句,即使是用于格式化和解析日期和时间,您也可以考虑不使用SimpleDateFormat 。众所周知,这很麻烦,而且已经过时了。而是将ThreeTenABP添加到您的Android项目中,以使用java.time(现代Java日期和时间API)。与之合作真是太好了。

链接