Java 打印mm:ss.ms秒表串的更好方法?

Java 打印mm:ss.ms秒表串的更好方法?,java,Java,我想显示一个格式化的字符串,包括分钟、秒和一个毫秒字符。这是我总结的内容(主要来自于这里的其他帖子): 因此,如果持续时间不超过59.9分钟(通常情况下),我将隐藏小时位置。我对毫秒位置做了一个非常糟糕的子字符串(),只是为了抓取第一个数字。有没有更好的方法来实现上述目标?我想要像这样的字符串: 00:14.9 00:05.1 00:05.2 33:20:4 etc 我必须为我正在制作的游戏重复生成这个字符串(上面每帧渲染一次),所以担心它会做很多不必要的工作 谢谢 毫无疑问,有更有效的方法来

我想显示一个格式化的字符串,包括分钟、秒和一个毫秒字符。这是我总结的内容(主要来自于这里的其他帖子):

因此,如果持续时间不超过59.9分钟(通常情况下),我将隐藏小时位置。我对毫秒位置做了一个非常糟糕的子字符串(),只是为了抓取第一个数字。有没有更好的方法来实现上述目标?我想要像这样的字符串:

00:14.9
00:05.1
00:05.2
33:20:4
etc
我必须为我正在制作的游戏重复生成这个字符串(上面每帧渲染一次),所以担心它会做很多不必要的工作


谢谢

毫无疑问,有更有效的方法来编写代码(实际上总是有的)

然而,在我的盒子上,你的函数每秒可以格式化130000个时间戳。显然,这对于您所陈述的用例来说已经足够快了

这就是说,如果我对它进行了编码,并且事先认为它可能处于性能关键路径上,我会避免
String.format()


在我的盒子上,每秒可以进行大约800万次转换。它还创建了更少的临时对象,这些临时对象最终不得不被垃圾收集。

您可以使用String.format一次将多个项目格式化为一个字符串

public static final String getTimeDurationAsString(long milliseconds) 
{
    int millis  = (int) (milliseconds % 1000);
    int seconds = (int) (milliseconds / 1000) % 60;
    int minutes = (int) ((milliseconds / (1000*60)) % 60);
    int hours   = (int) ((milliseconds / (1000*60*60)) % 24);

    string hours = "";
    if(hours > 0)
        hours = String.format("%02d:", hours);
    return hours + String.format("%0$:%1$:%2$", minutes, seconds, millis / 100);
}

要将毫秒转换为可以使用的其他单位

小型演示—它能做什么:

long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis));

String.format("%02d:%02d", minutes, seconds);
但您真正想做的是将毫秒更改为简单日期:

Date date = new Date(milliseconds);
SimpleDateFormat formatter = new SimpleDateFormat("mm:ss.S");
System.out.println(formatter.format(date));
输出:

getTimeDurationAsString(14009) => 00:14.9
getTimeDurationAsString(2000004) => 33:20.4

我认为Joda Time提供了最干净的解决方案。它可能不是性能最好的,因为它非常强大和灵活。但是它有适当的类型来表示时间的持续时间,这就是你正在做的,这给了它一个很好的机会去表现

对于Joda Time来说,这很简单:

private static final PeriodType MSM_PERIOD_TYPE = PeriodType.forFields(new DurationFieldType[]{
        DurationFieldType.minutes(),
        DurationFieldType.seconds(),
        DurationFieldType.millis()});

public static String getTimeDurationAsString(long milliseconds) {
    Period period = new Duration(milliseconds).toPeriod(MSM_PERIOD_TYPE);

    return String.format("%02d:%02d.%01d",
            period.getMinutes(),
            period.getSeconds(),
            period.getMillis() / 100);
}
如果您知道周期永远不会大于或等于一小时,那么您甚至不需要
MSM\u period\u TYPE

至于性能最好的解决方案……我真的无法想象,当涉及到游戏的渲染代码时,任何给定的解决方案都会成为一个因素。通过避免使用
String.format
,您可以节省一点,但考虑到这会使代码更加混乱,这似乎是一种无效的优化


Joda Time还有一个
PeriodFormatter
类(使用
PeriodFormatterBuilder
构建),但我没有找到一种干净的方法来包含十分之一秒,就像你所希望的那样。

你分析过应用程序的CPU使用情况,看看这个方法是否重要吗?我很惊讶这个方法得到了升级。第一个版本是完全错误的。当您添加小时组件时,第二个版本会出错(由于时区转换)。即使小时版本会出错,问题是:“打印mm:ss.ms的更好方法”
getTimeDurationAsString(14009) => 00:14.9
getTimeDurationAsString(2000004) => 33:20.4
private static final PeriodType MSM_PERIOD_TYPE = PeriodType.forFields(new DurationFieldType[]{
        DurationFieldType.minutes(),
        DurationFieldType.seconds(),
        DurationFieldType.millis()});

public static String getTimeDurationAsString(long milliseconds) {
    Period period = new Duration(milliseconds).toPeriod(MSM_PERIOD_TYPE);

    return String.format("%02d:%02d.%01d",
            period.getMinutes(),
            period.getSeconds(),
            period.getMillis() / 100);
}