【问题标题】:calculate elapsed time and display it in Java计算经过的时间并用Java显示
【发布时间】:2018-03-02 20:50:25
【问题描述】:

对于这个问题,stackoverflow 似乎没有简单的答案。我只是想获得两个日历实例之间的差异并显示在 HH:mm:ss.SSS

到目前为止,我有

SimpleDateFormat dateFormat = new                      
  SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");           
  Calendar start = Calendar.getInstance();               
  say("start time:"+dateFormat.format(start.getTime())); 

和

 Calendar ending = Calendar.getInstance();              
  say("ending time:"+dateFormat.format(ending.getTime()));
 long milli = ending.getTime().getTime()      
             - start.getTime().getTime();     
 long sec = milli / 1000; // millisec to sec  
 say("elapsed time: " + sec + "." + milli );  

确实可以显示两次。

 start time: 2018-03-02 15:44:41.194  
*** program runs ***
 ending time:2018-03-02 15:44:41.198 
 elapsed time: 0.4                   

但不应该是 0.004 秒吗?

请不要 JodaTime 回答。本店不支持。

【问题讨论】:

  • 您使用的是什么版本的 Java?
  • 经过的时间是 4 毫秒。如果您希望它显示 0.004,您应该将 seconds 设为 double。
  • 除非您使用自定义格式化程序,否则不会打印前导零。
  • 使用java.time API 会更简单更轻松
  • “但它不应该说 0.004 秒吗?” - 为什么?

标签: java date calendar


【解决方案1】:
    Instant start = Instant.now();

和

    Instant end = Instant.now();
    long milli = ChronoUnit.MILLIS.between(start, end);
    System.out.format(Locale.ENGLISH, "elapsed time: %.3f%n", milli / 1000.0);

在我的电脑上打印出来

经过的时间:0.004

当然,使用String.format 或System.out.format() 格式化也适用于您测量毫秒的方式。

如果需要,使用 Java 9,您可以(至少在某些计算机上)有更多小数:

    System.out.println("elapsed time: " 
            +  ChronoUnit.NANOS.between(start, end) / (double) TimeUnit.SECONDS.toNanos(1));

我明白了

经过时间:0.003739

【讨论】:

  • 该值可以在毫秒和分钟之间变化。可能不需要几个小时。仍在寻找解决方案。
【解决方案2】:

我为你写了一个小函数,它返回一个数字作为一个字符串,你想填多少“0”就填多少。

public String getStringNumber(long number, int displaySize) {
    String str = new String();
    int length = String.valueOf(number).length();
    while (length++ < displaySize)
        str += "0";
    str += number;
    return str;
}

现在你可以在你的代码中替换

say("elapsed time: " + sec + "." + getStringNumber(milli, 4));

【讨论】:

  • 谢谢 - 这对我有用。只需几毫秒(milli, 3)。所以这是Java?在 COBOL 中,我可以用零行代码做到这一点。哦,好吧。
  • @BaruchAtta 从技术上讲,在 Java 中,您可以在一个 String.format("%05d", yournumber); 中完成操作,但是“java 零填充字符串”的快速 google 会告诉您 ;)
  • 我正在删除您的答案作为解决方案,因为它显示 77 秒和 213 毫秒为 77213。不是正确的答案。我会寻找正确位置的小数点 77.213。
  • 好吧,那不是你要求的,那你必须say("elapsed time: " +getStringNumber(sec, 2) + "." + getStringNumber(milli, 3));
  • 我要求“在 HH:mm:ss.SSS 中显示”。感谢您的尝试。
【解决方案3】:

我终于找到了这个解决方案。它很尴尬而且不是很优雅,但它确实有效。

日历结束 = Calendar.getInstance();
say("结束时间:"+dateFormat.format(ending.getTime()));

long milli = ending.getTime().getTime()
- start.getTime().getTime();

长小时 = TimeUnit.MILLISECONDS.toHours(milli) % 24;
长 min = TimeUnit.MILLISECONDS.toMinutes(milli) % 60;
长秒 = TimeUnit.MILLISECONDS.toSeconds(milli) % 60;
长 mls = 毫 % 1000;
字符串经过 = String.format("%02d:%02d:%02d.%03d", hrs,
分钟、秒、毫升);

say("经过的时间:" + elaps);

解释如下:我将两个 Calendar 变量转换为 long,然后减去。然后我将 Long 格式化为 hh:mm:ss.SSS 格式的字符串,这是我首先想要的。

这是输出

结束时间:2018-03-05 15:07:17.923
经过时间:00:01:15.964

【讨论】:

  • 再看这个解决方案,真是太惊喜了。 TimeUnit.MILLISECONDS.toHours(milli) 应该返回一个整数。或者它也有这个选项?
【解决方案4】:

好的,所以,我只是想不通,无需尝试执行任何花哨的操作,您可以使用 Java 8 日期/时间 API,它提供了计算两个时间点之间差异的功能.

因此,接受您的输入,并通过下面的代码运行它,它会输出

2018-03-02T15:44:41.194
2018-03-02T15:44:41.198
0.004

现在,就个人而言,我会采用这个概念并简单地创建一个 DurationFormatter,它可以采用 Duration 并吐出您所需的格式,但这里的想法是为您提供一个起点。

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Test {

    public static void main(String[] args) {
        String startTime = "2018-03-02 15:44:41.194";
        String endTime = "2018-03-02 15:44:41.198";

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);

        System.out.println(startDateTime);
        System.out.println(endDateTime);

        Duration duration = Duration.between(startDateTime, endDateTime);

        long hours = duration.toHours();
        duration = duration.minusHours(hours);
        long mins = duration.toMinutes();
        duration = duration.minusMinutes(mins);
        long secs = duration.getSeconds();
        duration = duration.minusSeconds(secs);
        long millis = duration.toMillis();

        StringBuilder sb = new StringBuilder(12);
        if (hours > 0) {
            sb.append(pad(hours, 2));
        }
        if (mins == 0 && sb.length() > 0) {
            sb.append(":00");
        } else if (mins > 0) {
            if (hours > 0) {
                sb.append(":");
            }
            sb.append(pad(mins, 2));
        }
        if (secs == 0 & sb.length() > 0) {
            sb.append(":00");
        } else if (secs > 0) {
            if (mins > 0) {
                sb.append(":");
            }
            sb.append(pad(secs, 2));
        }
        if (millis == 0 & sb.length() > 0) {
            sb.append(".00");
        } else if (millis > 0) {
            if (secs > 0 || sb.length() > 0) {
                sb.append(".");
            } else if (sb.length() == 0) {
                sb.append("0.");
            }
            sb.append(pad(millis, 3));
        }

        System.out.println(sb.toString());
    }

    public static String pad(long value, long length) {
        return String.format("%0" + length + "d", value);
    }

}

现在,如果我们将输入更改为...

String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:44:41.198";

输出

144:00:00.004

或者如果我们使用

String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:15:41.198";

输出

143:31:00.004

或者

String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:15:50.198";

输出

143:31:09.004

或者

2018-03-02T15:44:41.194
2018-03-02T15:50:41.194

输出

06:00.00

...对我来说,这就是它变得奇怪的地方,技术上它是正确的(6 分钟),但从格式来看,很难准确推断出它的含义

在这里我可能会想使用更像String.format("%02d:%02d:%02d.%04d", hours, mins, secs, millis) 的东西,它会输出00:06:00.0000,但这一切都满足你的需要。您需要决定如何最好地获取原始信息并根据您的需要呈现它,但有几个不同的想法

【讨论】:

  • 如果我说我喜欢你的回答,你会否决我的问题?你一定在这个答案上花了很多时间。显示了很多工作。我使用 Calendar 类的原因是因为我上次检查时 Date 类被贬值了。现在我们有了这个 LocalDateTime 类和 Duration 类。这一切在哪里结束????这个“日期”和时间处理似乎随着 Java 的每个新版本而改变。顺便说一句,我的解决方案有六行。您的解决方案可能有一百个。或五十。努力得 A,优雅得 C。感谢收看。
  • @BaruchAtta 首先,我没有否决你的问题,相信我,如果我有,你会知道的。其次,现在可以了。第三,是的,我可能会对新 API 感到困惑,当他们只有日期和日历时,这已经够糟糕了。日期/时间 API 是日期/日历的替代品。实际上,我的核心答案只有 14 行(如果我们假设您不想要可变格式)并且可以减少,但我总是更喜欢可读性而不是“优雅”,但从事物的声音来看,你是永远不会满足
  • @BaruchAtta 您还必须认识到,日期/时间操作比简单地减去两个时间点要复杂得多,而在短时间内它可能不会导致“大”问题,越大范围,越是麻烦。最后,任何使用简单算术的答案都是错误的,并且越是依赖结果的准确性(甚至只是到第二级),问题就越严重。这就是 JodaTime 和新的日期/时间 API 等库存在的原因
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 2020-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多