我困惑。在偶然发现这个线程后,我试图弄清楚如何格式化一个具有hh:mm:ss格式的倒计时计时器。
这是我的尝试
//hh:mm:ss
String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
因此,当我尝试一个像3600000ms这样的值时,我得到01:59:00,这是错误的,因为它应该是01:00:00。显然我的逻辑有问题,但现在,我看不出是什么!
有人能帮忙吗?
编辑-
固定它。以下是将毫秒格式化为hh:mm:ss格式的正确方法
//hh:mm:ss
String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))));
问题是这个TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))。它应该是这个TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))。
你真的很接近:
String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), // The change is in this line
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
你用分钟而不是小时将小时转换为毫秒。
顺便说一句,我喜欢你使用TimeUnit API:)
下面是一些测试代码:
public static void main(String[] args) throws ParseException {
long millis = 3600000;
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
System.out.println(hms);
}
输出:
01:00:00
我意识到我上面的代码可以通过使用模除法而不是减法来大大简化:
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) % TimeUnit.HOURS.toMinutes(1),
TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1));
仍然使用TimeUnit API为所有魔术值,并给出完全相同的输出。
4个实现的测试结果
必须为巨大的数据做大量的格式化,需要最好的性能,所以下面是(令人惊讶的)结果:
For (int I = 0;I < 1000000;我+ +){
FUNCTION_CALL
}
持续时间:
combinationFormatter: 196 millis
formatDuration: 272 millis
apacheFormat: 754 millis
formatTimeUnit: 2216 millis
public static String apacheFormat(long millis) throws ParseException {
return DurationFormatUtils.formatDuration(millis, "HH:mm:ss");
}
public static String formatTimeUnit(long millis) throws ParseException {
String formatted = String.format(
"%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
return formatted;
}
public static String formatDuration(final long millis) {
long seconds = (millis / 1000) % 60;
long minutes = (millis / (1000 * 60)) % 60;
long hours = millis / (1000 * 60 * 60);
StringBuilder b = new StringBuilder();
b.append(hours == 0 ? "00" : hours < 10 ? String.valueOf("0" + hours) :
String.valueOf(hours));
b.append(":");
b.append(minutes == 0 ? "00" : minutes < 10 ? String.valueOf("0" + minutes) :
String.valueOf(minutes));
b.append(":");
b.append(seconds == 0 ? "00" : seconds < 10 ? String.valueOf("0" + seconds) :
String.valueOf(seconds));
return b.toString();
}
public static String combinationFormatter(final long millis) {
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
long hours = TimeUnit.MILLISECONDS.toHours(millis);
StringBuilder b = new StringBuilder();
b.append(hours == 0 ? "00" : hours < 10 ? String.valueOf("0" + hours) :
String.valueOf(hours));
b.append(":");
b.append(minutes == 0 ? "00" : minutes < 10 ? String.valueOf("0" + minutes) :
String.valueOf(minutes));
b.append(":");
b.append(seconds == 0 ? "00" : seconds < 10 ? String.valueOf("0" + seconds) :
String.valueOf(seconds));
return b.toString();
}