我有一个最奇怪的问题-在我们的应用程序中,一个地方,我们使用SimpleDateFormat显示了以mm:ss格式化的时间。问题是我们在美国有一个客户抱怨他们将5分钟格式化为35:00。我缩小了范围,以与我正在测试的值相同的值调用了SimpleDateFormat.format,但它们的分钟数用3而不是0填充。
问题是我无法重现该问题,他们告诉我他们已测试并在4种不同的设备上得到它:
我也在小米Mi A1(以及其他一些设备)上进行测试,但是尝试的时间还可以。
时间是这样格式化的:
SimpleDateFormat timeFormatter = new SimpleDateFormat("mm:ss", Locale.getDefault());
timeFormatter.format(new Date(5*60*1000));
有人看到过这样的东西吗?
答案 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
将其格式化为两位数。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)。与之合作真是太好了。
java.time
。java.time
。java.time
向Java 6和7(JSR-310的ThreeTen)的反向端口。