如何在Java中度量时间流逝?

时间:2022-11-30 12:01:00

Possible Duplicate:
How do I calculate the elapsed time of an event in java?

可能的重复:如何在java中计算事件经过的时间?

I want to have something like this:

我想要这样的东西:

public class Stream
{
    public startTime;
    public endTime;

    public getDuration()
    {
        return startTime - endTime;
    }
}

Also it is important that for example if the startTime it's 23:00 and endTime 1:00 to get a duration of 2:00.

同样重要的是,如果开始时间是23:00,结束时间是1:00那么持续时间是2:00。

Which types to use in order to accomplish this in Java?

为了在Java中实现这一点,需要使用哪些类型?

15 个解决方案

#1


557  

Unfortunately, none of the ten answers posted so far are quite right.

不幸的是,到目前为止公布的10个答案中没有一个是完全正确的。

If you are measuring elapsed time, and you want it to be correct, you must use System.nanoTime(). You cannot use System.currentTimeMillis(), unless you don't mind your result being wrong.

如果您正在测量经过的时间,并且您希望它是正确的,那么您必须使用System.nanoTime()。您不能使用System.currentTimeMillis(),除非您不介意您的结果是错误的。

The purpose of nanoTime is to measure elapsed time, and the purpose of currentTimeMillis is to measure wall-clock time. You can't use the one for the other purpose. The reason is that no computer's clock is perfect; it always drifts and occasionally needs to be corrected. This correction might either happen manually, or in the case of most machines, there's a process that runs and continually issues small corrections to the system clock ("wall clock"). These tend to happen often. Another such correction happens whenever there is a leap second.

nanoTime的目的是度量流逝时间,currentTimeMillis的目的是度量壁挂式时钟时间。你不能用这个来做另一个目的。原因是没有计算机的时钟是完美的;它总是飘忽不定,偶尔需要纠正。这种修正可能会手动发生,或者在大多数机器的情况下,有一个进程运行并不断地对系统时钟(“挂钟”)进行小的修正。这种情况经常发生。每当出现闰秒时,就会出现另一种修正。

Since nanoTime's purpose is to measure elapsed time, it is unaffected by any of these small corrections. It is what you want to use. Any timings currently underway with currentTimeMillis will be off -- possibly even negative.

由于nanoTime的目的是度量流逝的时间,因此它不受任何这些小更正的影响。这是你想用的。目前与currentTimeMillis正在进行的任何计时都将关闭——甚至可能是负面的。

You may say, "this doesn't sound like it would ever really matter that much," to which I say, maybe not, but overall, isn't correct code just better than incorrect code? Besides, nanoTime is shorter to type anyway.

你可能会说,“这听起来并没有那么重要,”我说,也许没有,但总的来说,正确的代码不比不正确的代码好吗?此外,无论如何,纳米时间比打字要短。

Previously posted disclaimers about nanoTime usually having only microsecond precision are valid. Also it can take more than a whole microsecond to invoke, depending on circumstances (as can the other one), so don't expect to time very very small intervals correctly.

以前发布的关于纳米时间的免责声明通常只有微秒精度是有效的。此外,根据不同的环境(另一个环境也是如此),调用它可能需要超过一微秒的时间,所以不要期望能够正确地对非常小的间隔计时。

#2


192  

Which types to use in order to accomplish this in Java?

为了在Java中实现这一点,需要使用哪些类型?

The short answer is a long. Now, more on how to measure...

简短的回答是长。现在,更多关于如何衡量…

System.currentTimeMillis()

The "traditional" way to do this is indeed to use System.currentTimeMillis():

传统的方法是使用System.currentTimeMillis():

long startTime = System.currentTimeMillis();
// ... do something ...
long estimatedTime = System.currentTimeMillis() - startTime;

o.a.c.l.t.StopWatch

Note that Commons Lang has a StopWatch class that can be used to measure execution time in milliseconds. It has methods methods like split(), suspend(), resume(), etc that allow to take measure at different points of the execution and that you may find convenient. Have a look at it.

注意,Commons Lang有一个秒表类,可用于以毫秒为单位度量执行时间。它有诸如split()、suspend()、resume()等方法,这些方法允许在执行的不同点进行度量,您可能会发现很方便。看一看。

System.nanoTime()

You may prefer to use System.nanoTime() if you are looking for extremely precise measurements of elapsed time. From its javadoc:

如果您正在寻找经过时间的非常精确的度量,您可能更喜欢使用System.nanoTime()。从它的javadoc。

long startTime = System.nanoTime();    
// ... the code being measured ...    
long estimatedTime = System.nanoTime() - startTime;

Jamon

Another option would be to use JAMon, a tool that gathers statistics (execution time, number of hit, average execution time, min, max, etc) for any code that comes between start() and stop() methods. Below, a very simple example:

另一种选择是使用JAMon,这是一种收集统计信息(执行时间、命中次数、平均执行时间、最小值、最大值等)的工具,用于处理开始()和停止()方法之间的任何代码。下面是一个非常简单的例子:

import com.jamonapi.*;
...
Monitor mon=MonitorFactory.start("myFirstMonitor");
...Code Being Timed...
mon.stop();

Check out this article on www.javaperformancetunning.com for a nice introduction.

查看www.javapercetunning.com上的这篇文章,获得一个不错的介绍。

Using AOP

Finally, if you don't want to clutter your code with these measurement (or if you can't change existing code), then AOP would be a perfect weapon. I'm not going to discuss this very deeply but I wanted at least to mention it.

最后,如果您不想用这些度量来打乱代码(或者如果您不能更改现有代码),那么AOP将是一种完美的武器。我不打算深入讨论这个问题但我想至少提一下。

Below, a very simple aspect using AspectJ and JAMon (here, the short name of the pointcut will be used for the JAMon monitor, hence the call to thisJoinPoint.toShortString()):

下面是一个使用AspectJ和JAMon的非常简单的方面(这里,切入点的短名称将用于JAMon监视器,因此调用thisJoinPoint.toShortString()):

public aspect MonitorAspect {
    pointcut monitor() : execution(* *.ClassToMonitor.methodToMonitor(..));

    Object arround() : monitor() {
        Monitor monitor = MonitorFactory.start(thisJoinPoint.toShortString());
        Object returnedObject = proceed();
        monitor.stop();
        return returnedObject;
    }
}

The pointcut definition could be easily adapted to monitor any method based on the class name, the package name, the method name, or any combination of these. Measurement is really a perfect use case for AOP.

切入点定义可以很容易地根据类名、包名、方法名或它们的任何组合来监视任何方法。度量实际上是AOP的一个完美用例。

#3


35  

Your new class:

你的新类:

public class TimeWatch {    
    long starts;

    public static TimeWatch start() {
        return new TimeWatch();
    }

    private TimeWatch() {
        reset();
    }

    public TimeWatch reset() {
        starts = System.currentTimeMillis();
        return this;
    }

    public long time() {
        long ends = System.currentTimeMillis();
        return ends - starts;
    }

    public long time(TimeUnit unit) {
        return unit.convert(time(), TimeUnit.MILLISECONDS);
    }
}

Usage:

用法:

    TimeWatch watch = TimeWatch.start();
    // do something
    long passedTimeInMs = watch.time();
    long passedTimeInSeconds = watch.time(TimeUnit.SECONDS);

Afterwards, the time passed can be converted to whatever format you like, with a calender for example

之后,所经过的时间可以转换为您喜欢的格式,例如日历

Greetz, GHad

Greetz,盖德

#4


18  

If the purpose is to simply print coarse timing information to your program logs, then the easy solution for Java projects is not to write your own stopwatch or timer classes, but just use the org.apache.commons.lang.time.StopWatch class that is part of Apache Commons Lang.

如果目的是简单地将粗糙的计时信息打印到程序日志中,那么Java项目的简单解决方案不是编写自己的秒表或计时器类,而是使用org.apache.common . Lang. time. stopwatch类,这是Apache Commons Lang的一部分。

final StopWatch stopwatch = new StopWatch();
stopwatch.start();
LOGGER.debug("Starting long calculations: {}", stopwatch);
...
LOGGER.debug("Time after key part of calcuation: {}", stopwatch);
...
LOGGER.debug("Finished calculating {}", stopwatch);

#5


13  

New Technology In Java 8+

We have new technology for this now built into Java 8 and later, the java.time framework.

我们在Java 8和后来的Java中已经有了新的技术。时间框架。

java.time

The java.time framework is defined by JSR 310, inspired by the highly successful Joda-Time project, extended by the ThreeTen-Extra project, and described in the Oracle Tutorial.

java。时间框架由JSR 310定义,灵感来自于非常成功的Joda-Time项目,由三个额外的项目扩展,并在Oracle教程中进行了描述。

The old date-time classes such as java.util.Date/.Calendar bundled with the earliest versions of Java have proven to be poorly designed, confusing, and troublesome. They are supplanted by the java.time classes.

旧的日期时间类,如java.util.Date/。与Java早期版本捆绑在一起的日历被证明设计糟糕、混乱且麻烦。它们被java取代了。时间类。

Resolution

Other answers discuss resolution.

其他答案讨论决议。

The java.time classes have nanosecond resolution, up to nine digits of a decimal fraction of a second. For example, 2016-03-12T04:29:39.123456789Z.

java。时间类有纳秒的分辨率,高达九位数的秒。例如,2016 - 03 - 12 - t04:29:39.123456789z。

Both the old java.util.Date/.Calendar classes and the Joda-Time classes have millisecond resolution (3 digits of fraction). For example, 2016-03-12T04:29:39.123Z.

*ava.util.Date /。日历类和Joda-Time类有毫秒级的分辨率(3位数的分数)。例如,2016 - 03 - 12 - t04:29:39.123z。

In Java 8, the current moment is fetched with up to only millisecond resolution because of a legacy issue. In Java 9 and later, the current time can be determined up to nanosecond resolution provided your computer’s hardware clock runs so finely.

在Java 8中,由于遗留问题,当前时刻的分辨率最高只有毫秒。在Java 9和以后的版本中,如果您的计算机的硬件时钟运行得非常好,那么当前的时间可以确定到纳秒的分辨率。

Time-Of-Day

If you truly want to work with only the time-of-day lacking any date or time zone, use the LocalTime class.

如果您真的想只使用一天中没有任何日期或时区的时间,请使用LocalTime类。

LocalTime sooner = LocalTime.of ( 17, 00 );
LocalTime later = LocalTime.of ( 19, 00 );

A Duration represents a span of time it terms of a count of seconds plus nanoseconds.

持续时间表示持续时间的跨度,即秒数加上纳秒数。

Duration duration = Duration.between ( sooner, later );

Dump to console.

转储到控制台。

System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );

sooner: 17:00 | later: 19:00 | duration: PT2H

更早:17:00 |稍后:19:00 |时间:PT2H。

ISO 8601

Notice the default output of Duration::toString is in standard ISO 8601 format. In this format, the P marks the beginning (as in 'Period'), and the T separates any years-months-days portion from the hours-minutes-seconds portion.

注意默认的持续时间输出:::toString是标准ISO 8601格式。在这种格式中,P表示开始(如“句点”),T将任何年、月、日部分与小时、分钟、秒部分分开。

Crossing Midnight

Unfortunately, working with time-of-day only gets tricky when you wrap around the clock crossing midnight. The LocalTime class handles this by assuming you want to go backwards to an earlier point in the day.

不幸的是,只有当你在午夜完成一天的工作时,工作才会变得棘手。LocalTime类通过假设您想要回溯到当天早些时候的某个点来处理这个问题。

Using the same code as above but going from 23:00 to 01:00 results in a negative twenty-two hours (PT-22H).

使用与上面相同的代码,但是从23:00到01:00将导致负22小时(PT-22H)。

LocalTime sooner = LocalTime.of ( 23, 0 );
LocalTime later = LocalTime.of ( 1, 0 );

sooner: 23:00 | later: 01:00 | duration: PT-22H

稍后23:00 | 01:00 |持续时间:PT-22H

Date-Time

If you intend to cross midnight, it probably makes sense for you to be working with date-time values rather than time-of-day-only values.

如果您打算跨越午夜,那么使用日期-时间值而不是只使用一天时间值可能是有意义的。

Time Zone

Time zone is crucial to dates. So we specify three items: (1) the desired date, (2) desired time-of-day, and (3) the time zone as a context by which to interpret that date and time. Here we arbitrarily choose the time zone of the Montréal area.

时区对日期至关重要。因此,我们指定了三个项目:(1)期望的日期;(2)期望的一天时间;(3)时区作为解释日期和时间的上下文。这里我们任意选择蒙特利尔地区的时区。

If you define the date by only an offset-from-UTC, use a ZoneOffset with a OffsetDateTime. If you have a full time zone (offset plus rules for handling anomalies such as Daylight Saving Time), use a ZoneId with a ZonedDateTime.

如果您仅通过一个offset-from-UTC定义日期,则使用带有OffsetDateTime的ZoneOffset。如果您有一个完整的时区(偏移量加上处理异常的规则,如夏令时),请使用带ZonedDateTime的ZoneId。

LocalDate localDate = LocalDate.of ( 2016, 1, 23 );
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime sooner = ZonedDateTime.of ( localDate, LocalTime.of ( 23, 0 ), zoneId );

We specify the later time as next day at 1:00 AM.

我们把晚一点的时间定为第二天凌晨一点。

ZonedDateTime later = ZonedDateTime.of ( localDate.plusDays ( 1 ), LocalTime.of ( 1, 0 ), zoneId );

We calculate the Duration in the same manner as seen above. Now we get the two hours expected by this Question.

我们按照上面看到的方式计算持续时间。现在我们得到了这个问题所期望的两个小时。

Duration duration = Duration.between ( sooner, later );

Dump to console.

转储到控制台。

System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );

sooner: 2016-01-23T23:00-05:00[America/Montreal] | later: 2016-01-24T01:00-05:00[America/Montreal] | duration: PT2H

早:2016-01-23T23:00-05:00[美国/蒙特利尔]|后:2016-01-24T01:00-05:00[美国/蒙特利尔]|持续时间:PT2H

Daylight Saving Time

If the date-times at hand had involved Daylight Saving Time (DST) or other such anomaly, the java.time classes would adjust as needed. Read class doc for details.

如果当前的日期时间涉及夏令时(DST)或其他类似的异常,则使用java。时间类将根据需要进行调整。详细信息请阅读class doc。


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java。time框架被构建到Java 8以及以后的版本中。这些类取代了麻烦的旧遗留日期时间类(如java.util)。日期,日历,& SimpleDateFormat。

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

现在处于维护模式的Joda-Time项目建议迁移到java。时间类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle教程。和搜索堆栈溢出为许多例子和解释。规范是JSR 310。

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

你可以交换java。时间对象直接与您的数据库。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java.sql。*类。

Where to obtain the java.time classes?

在哪里获得java。时间类?

  • Java SE 8, Java SE 9, Java SE 10, and later
    • Built-in.
    • 内置的。
    • Part of the standard Java API with a bundled implementation.
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9 adds some minor features and fixes.
    • Java 9添加了一些次要的特性和修复。
  • Java SE 8, Java SE 9, Java SE 10,以及后来的内置。带有捆绑实现的标准Java API的一部分。Java 9添加了一些次要的特性和修复。
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • 大部分java。时间功能在三个回端移植到Java 6和7。
  • Java SE 6和Java SE 7大部分的Java。时间功能在三个回端移植到Java 6和7。
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • java的Android bundle实现的后续版本。时间类。
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
    • 对于早期的Android (<26), ThreeTenABP项目适用于three - backport(如上所述)。看到如何使用ThreeTenABP ....
  • Android后期版本的java捆绑包实现。时间类。对于早期的Android (<26), ThreeTenABP项目适用于three - backport(如上所述)。看到如何使用ThreeTenABP ....

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

三个额外的项目扩展了java。时间和额外的类。这个项目是java.time未来可能增加的一个试验场。您可以在这里找到一些有用的课程,如间隔、年周、年季等。

#6


7  

Java provides the static method System.currentTimeMillis(). And that's returning a long value, so it's a good reference. A lot of other classes accept a 'timeInMillis' parameter which is long as well.

Java提供了静态方法System.currentTimeMillis()。这是返回一个很长的值,这是一个很好的参考。许多其他类都接受“timeInMillis”参数,该参数也很长。

And a lot of people find it easier to use the Joda Time library to do calculations on dates and times.

很多人发现使用Joda Time库来计算日期和时间更容易。

#7


6  

Which types to use in order to accomplish this in Java?

为了在Java中实现这一点,需要使用哪些类型?

Answer: long

答:长

public class Stream {
    public long startTime;
    public long endTime;

    public long getDuration() {
        return endTime - startTime;
    }
    // I  would add
    public void start() {
        startTime = System.currentTimeMillis();
    }
    public void stop() {
         endTime = System.currentTimeMillis();
     }
}

Usage:

用法:

  Stream s = .... 

  s.start();

  // do something for a while 

  s.stop();

  s.getDuration(); // gives the elapsed time in milliseconds. 

That's my direct answer for your first question.

这就是我对你第一个问题的直接回答。

For the last "note" I would suggest you to use Joda Time. It contains an interval class suitable for what you need.

最后,我建议你使用Joda Time。它包含一个适合您需要的interval类。

#8


6  

It is worth noting that

值得注意的是。

  • System.currentTimeMillis() has only millisecond accuracy at best. At worth its can be 16 ms on some windows systems. It has a lower cost that alternatives < 200 ns.
  • currenttimemillis()充其量只有毫秒级的准确度。在某些windows系统上,它可以值16毫秒。它的成本低于200纳秒。
  • System.nanoTime() is only micro-second accurate on most systems and can jump on windows systems by 100 microseconds (i.e sometimes it not as accurate as it appears)
  • System.nanoTime()在大多数系统中都只有微秒的准确率,并且可以在windows系统中跳转100微秒(i)。e有时它不像看上去的那么准确)
  • Calendar is a very expensive way to calculate time. (i can think of apart from XMLGregorianCalendar) Sometimes its the most appropriate solution but be aware you should only time long intervals.
  • 日历是计算时间的一种非常昂贵的方法。(除了XMLGregorianCalendar)有时这是最合适的解决方案,但要注意,您应该只使用长时间间隔。

#9


3  

If you are writing an application that must deal with durations of time, then please take a look at Joda-Time which has class specifically for handling Durations, Intervals, and Periods. Your getDuration() method looks like it could return a Joda-Time Interval:

如果您正在编写一个必须处理时间间隔的应用程序,那么请查看Joda-Time,它有专门用于处理时间间隔和周期的类。您的getDuration()方法看起来可以返回一个Joda-Time间隔:

DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);

public Interval getInterval() {
    Interval interval = new Interval(start, end);
}

#10


2  

If you prefer using Java's Calendar API you can try this,

如果你喜欢使用Java的日历API,你可以试试这个,

Date startingTime = Calendar.getInstance().getTime();
//later on
Date now = Calendar.getInstance().getTime();
long timeElapsed = now.getTime() - startingTime.getTime();

#11


1  

If you're getting your timestamps from System.currentTimeMillis(), then your time variables should be longs.

如果您正在从System.currentTimeMillis()获取时间戳,那么您的时间变量应该很长。

#12


1  

Byte Stream Reader Elapsed Time for 23.7 MB is 96 secs

import java.io.*;
import java.io.IOException;
import java.util.Scanner;

class ElaspedTimetoCopyAFileUsingByteStream
{

    private long startTime = 0;
    private long stopTime = 0;
    private boolean running = false;


    public void start() 
    {
        this.startTime = System.currentTimeMillis();
        this.running = true;
    }


    public void stop() 
    {
        this.stopTime = System.currentTimeMillis();
        this.running = false;
    }



    public long getElapsedTime() 
    {
        long elapsed;
        if (running) {
             elapsed = (System.currentTimeMillis() - startTime);
        }
        else {
            elapsed = (stopTime - startTime);
        }
        return elapsed;
    }



    public long getElapsedTimeSecs()                 
    {
        long elapsed;
        if (running) 
        {
            elapsed = ((System.currentTimeMillis() - startTime) / 1000);
        }
        else
        {
            elapsed = ((stopTime - startTime) / 1000);
        }
        return elapsed;
    }





    public static void main(String[] args) throws IOException
    {
        ElaspedTimetoCopyAFileUsingByteStream  s = new ElaspedTimetoCopyAFileUsingByteStream();
        s.start();

        FileInputStream in = null;
        FileOutputStream out = null;

      try {
         in = new FileInputStream("vowels.txt");   // 23.7  MB File
         out = new FileOutputStream("output.txt");

         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }



        s.stop();
        System.out.println("elapsed time in seconds: " + s.getElapsedTimeSecs());
    }
}

[Elapsed Time for Byte Stream Reader][1]

**Character Stream Reader Elapsed Time for 23.7 MB is 3 secs**

import java.io.*;
import java.io.IOException;
import java.util.Scanner;

class ElaspedTimetoCopyAFileUsingCharacterStream
{

    private long startTime = 0;
    private long stopTime = 0;
    private boolean running = false;


    public void start() 
    {
        this.startTime = System.currentTimeMillis();
        this.running = true;
    }


    public void stop() 
    {
        this.stopTime = System.currentTimeMillis();
        this.running = false;
    }



    public long getElapsedTime() 
    {
        long elapsed;
        if (running) {
             elapsed = (System.currentTimeMillis() - startTime);
        }
        else {
            elapsed = (stopTime - startTime);
        }
        return elapsed;
    }



    public long getElapsedTimeSecs()                 
    {
        long elapsed;
        if (running) 
        {
            elapsed = ((System.currentTimeMillis() - startTime) / 1000);
        }
        else
        {
            elapsed = ((stopTime - startTime) / 1000);
        }
        return elapsed;
    }





    public static void main(String[] args) throws IOException
    {
        ElaspedTimetoCopyAFileUsingCharacterStream  s = new ElaspedTimetoCopyAFileUsingCharacterStream();
        s.start();

         FileReader in = null;                // CharacterStream Reader
      FileWriter out = null;

      try {
         in = new FileReader("vowels.txt");    // 23.7 MB
         out = new FileWriter("output.txt");

         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }

              s.stop();
        System.out.println("elapsed time in seconds: " + s.getElapsedTimeSecs());
    }
}


[Elapsed Time for Character Stream Reader][2]


  [1]: https://i.stack.imgur.com/hYo8y.png
  [2]: https://i.stack.imgur.com/xPjCK.png

#13


0  

i found this code to be useful when timing things:

我发现这个代码在计时时很有用:

public class Et {
    public Et() {
    reset();
    }
    public void reset() {
    t0=System.nanoTime();
    }
    public long t0() {
        return t0;
    }
    public long dt() {
        return System.nanoTime()-t0();
    }
    public double etms() {
    return etms(dt());
    }
    @Override public String toString() {
        return etms()+" ms.";
    }
    public static double etms(long dt) {
        return dt/1000000.; // 1_000_000. breaks cobertura
    }
    private Long t0;
}

#14


0  

Use this:

用这个:

SimpleDateFormat format = new SimpleDateFormat("HH:mm");

Date d1 = format.parse(strStartTime);
Date d2 = format.parse(strEndTime);

long diff = d2.getTime() - d1.getTime();
long diffSeconds,diffMinutes,diffHours;

if (diff > 0) {
diffSeconds = diff / 1000 % 60;
diffMinutes = diff / (60 * 1000) % 60;
diffHours = diff / (60 * 60 * 1000);
}
else{
long diffpos = (24*((60 * 60 * 1000))) + diff;
diffSeconds = diffpos / 1000 % 60;
diffMinutes = diffpos / (60 * 1000) % 60;
diffHours = (diffpos / (60 * 60 * 1000));
}

(Also it is important that for example if the startTime it's 23:00 and endTime 1:00 to get a duration of 2:00.)

(同样重要的是,如果开始时间是23:00,结束时间是1:00,则持续时间是2:00。)

the "else" part can get it correct

“else”部分可以得到正确的答案

#15


0  

I built a formatting function based on stuff I stole off SO. I needed a way of "profiling" stuff in log messages, so I needed a fixed length duration message.

我构建了一个基于我偷来的东西的格式化函数。我需要一种在日志消息中“分析”内容的方法,所以我需要一个固定长度的持续时间消息。

public static String GetElapsed(long aInitialTime, long aEndTime, boolean aIncludeMillis)
{
  StringBuffer elapsed = new StringBuffer();

  Map<String, Long> units = new HashMap<String, Long>();

  long milliseconds = aEndTime - aInitialTime;

  long seconds = milliseconds / 1000;
  long minutes = milliseconds / (60 * 1000);
  long hours = milliseconds / (60 * 60 * 1000);
  long days = milliseconds / (24 * 60 * 60 * 1000);

  units.put("milliseconds", milliseconds);
  units.put("seconds", seconds);
  units.put("minutes", minutes);
  units.put("hours", hours);
  units.put("days", days);

  if (days > 0)
  {
    long leftoverHours = hours % 24;
    units.put("hours", leftoverHours);
  }

  if (hours > 0)
  {
    long leftoeverMinutes = minutes % 60;
    units.put("minutes", leftoeverMinutes);
  }

  if (minutes > 0)
  {
    long leftoverSeconds = seconds % 60;
    units.put("seconds", leftoverSeconds);
  }

  if (seconds > 0)
  {
    long leftoverMilliseconds = milliseconds % 1000;
    units.put("milliseconds", leftoverMilliseconds);
  }

  elapsed.append(PrependZeroIfNeeded(units.get("days")) + " days ")
      .append(PrependZeroIfNeeded(units.get("hours")) + " hours ")
      .append(PrependZeroIfNeeded(units.get("minutes")) + " minutes ")
      .append(PrependZeroIfNeeded(units.get("seconds")) + " seconds ")
      .append(PrependZeroIfNeeded(units.get("milliseconds")) + " ms");

  return elapsed.toString();

}

private static String PrependZeroIfNeeded(long aValue)
{
  return aValue < 10 ? "0" + aValue : Long.toString(aValue);
}

And a test class:

和一个测试类:

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import junit.framework.TestCase;

public class TimeUtilsTest extends TestCase
{

  public void testGetElapsed()
  {
    long start = System.currentTimeMillis();
    GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance();
    calendar.setTime(new Date(start));

    calendar.add(Calendar.MILLISECOND, 610);
    calendar.add(Calendar.SECOND, 35);
    calendar.add(Calendar.MINUTE, 5);
    calendar.add(Calendar.DAY_OF_YEAR, 5);

    long end = calendar.getTimeInMillis();

    assertEquals("05 days 00 hours 05 minutes 35 seconds 610 ms", TimeUtils.GetElapsed(start, end, true));

  }

}

#1


557  

Unfortunately, none of the ten answers posted so far are quite right.

不幸的是,到目前为止公布的10个答案中没有一个是完全正确的。

If you are measuring elapsed time, and you want it to be correct, you must use System.nanoTime(). You cannot use System.currentTimeMillis(), unless you don't mind your result being wrong.

如果您正在测量经过的时间,并且您希望它是正确的,那么您必须使用System.nanoTime()。您不能使用System.currentTimeMillis(),除非您不介意您的结果是错误的。

The purpose of nanoTime is to measure elapsed time, and the purpose of currentTimeMillis is to measure wall-clock time. You can't use the one for the other purpose. The reason is that no computer's clock is perfect; it always drifts and occasionally needs to be corrected. This correction might either happen manually, or in the case of most machines, there's a process that runs and continually issues small corrections to the system clock ("wall clock"). These tend to happen often. Another such correction happens whenever there is a leap second.

nanoTime的目的是度量流逝时间,currentTimeMillis的目的是度量壁挂式时钟时间。你不能用这个来做另一个目的。原因是没有计算机的时钟是完美的;它总是飘忽不定,偶尔需要纠正。这种修正可能会手动发生,或者在大多数机器的情况下,有一个进程运行并不断地对系统时钟(“挂钟”)进行小的修正。这种情况经常发生。每当出现闰秒时,就会出现另一种修正。

Since nanoTime's purpose is to measure elapsed time, it is unaffected by any of these small corrections. It is what you want to use. Any timings currently underway with currentTimeMillis will be off -- possibly even negative.

由于nanoTime的目的是度量流逝的时间,因此它不受任何这些小更正的影响。这是你想用的。目前与currentTimeMillis正在进行的任何计时都将关闭——甚至可能是负面的。

You may say, "this doesn't sound like it would ever really matter that much," to which I say, maybe not, but overall, isn't correct code just better than incorrect code? Besides, nanoTime is shorter to type anyway.

你可能会说,“这听起来并没有那么重要,”我说,也许没有,但总的来说,正确的代码不比不正确的代码好吗?此外,无论如何,纳米时间比打字要短。

Previously posted disclaimers about nanoTime usually having only microsecond precision are valid. Also it can take more than a whole microsecond to invoke, depending on circumstances (as can the other one), so don't expect to time very very small intervals correctly.

以前发布的关于纳米时间的免责声明通常只有微秒精度是有效的。此外,根据不同的环境(另一个环境也是如此),调用它可能需要超过一微秒的时间,所以不要期望能够正确地对非常小的间隔计时。

#2


192  

Which types to use in order to accomplish this in Java?

为了在Java中实现这一点,需要使用哪些类型?

The short answer is a long. Now, more on how to measure...

简短的回答是长。现在,更多关于如何衡量…

System.currentTimeMillis()

The "traditional" way to do this is indeed to use System.currentTimeMillis():

传统的方法是使用System.currentTimeMillis():

long startTime = System.currentTimeMillis();
// ... do something ...
long estimatedTime = System.currentTimeMillis() - startTime;

o.a.c.l.t.StopWatch

Note that Commons Lang has a StopWatch class that can be used to measure execution time in milliseconds. It has methods methods like split(), suspend(), resume(), etc that allow to take measure at different points of the execution and that you may find convenient. Have a look at it.

注意,Commons Lang有一个秒表类,可用于以毫秒为单位度量执行时间。它有诸如split()、suspend()、resume()等方法,这些方法允许在执行的不同点进行度量,您可能会发现很方便。看一看。

System.nanoTime()

You may prefer to use System.nanoTime() if you are looking for extremely precise measurements of elapsed time. From its javadoc:

如果您正在寻找经过时间的非常精确的度量,您可能更喜欢使用System.nanoTime()。从它的javadoc。

long startTime = System.nanoTime();    
// ... the code being measured ...    
long estimatedTime = System.nanoTime() - startTime;

Jamon

Another option would be to use JAMon, a tool that gathers statistics (execution time, number of hit, average execution time, min, max, etc) for any code that comes between start() and stop() methods. Below, a very simple example:

另一种选择是使用JAMon,这是一种收集统计信息(执行时间、命中次数、平均执行时间、最小值、最大值等)的工具,用于处理开始()和停止()方法之间的任何代码。下面是一个非常简单的例子:

import com.jamonapi.*;
...
Monitor mon=MonitorFactory.start("myFirstMonitor");
...Code Being Timed...
mon.stop();

Check out this article on www.javaperformancetunning.com for a nice introduction.

查看www.javapercetunning.com上的这篇文章,获得一个不错的介绍。

Using AOP

Finally, if you don't want to clutter your code with these measurement (or if you can't change existing code), then AOP would be a perfect weapon. I'm not going to discuss this very deeply but I wanted at least to mention it.

最后,如果您不想用这些度量来打乱代码(或者如果您不能更改现有代码),那么AOP将是一种完美的武器。我不打算深入讨论这个问题但我想至少提一下。

Below, a very simple aspect using AspectJ and JAMon (here, the short name of the pointcut will be used for the JAMon monitor, hence the call to thisJoinPoint.toShortString()):

下面是一个使用AspectJ和JAMon的非常简单的方面(这里,切入点的短名称将用于JAMon监视器,因此调用thisJoinPoint.toShortString()):

public aspect MonitorAspect {
    pointcut monitor() : execution(* *.ClassToMonitor.methodToMonitor(..));

    Object arround() : monitor() {
        Monitor monitor = MonitorFactory.start(thisJoinPoint.toShortString());
        Object returnedObject = proceed();
        monitor.stop();
        return returnedObject;
    }
}

The pointcut definition could be easily adapted to monitor any method based on the class name, the package name, the method name, or any combination of these. Measurement is really a perfect use case for AOP.

切入点定义可以很容易地根据类名、包名、方法名或它们的任何组合来监视任何方法。度量实际上是AOP的一个完美用例。

#3


35  

Your new class:

你的新类:

public class TimeWatch {    
    long starts;

    public static TimeWatch start() {
        return new TimeWatch();
    }

    private TimeWatch() {
        reset();
    }

    public TimeWatch reset() {
        starts = System.currentTimeMillis();
        return this;
    }

    public long time() {
        long ends = System.currentTimeMillis();
        return ends - starts;
    }

    public long time(TimeUnit unit) {
        return unit.convert(time(), TimeUnit.MILLISECONDS);
    }
}

Usage:

用法:

    TimeWatch watch = TimeWatch.start();
    // do something
    long passedTimeInMs = watch.time();
    long passedTimeInSeconds = watch.time(TimeUnit.SECONDS);

Afterwards, the time passed can be converted to whatever format you like, with a calender for example

之后,所经过的时间可以转换为您喜欢的格式,例如日历

Greetz, GHad

Greetz,盖德

#4


18  

If the purpose is to simply print coarse timing information to your program logs, then the easy solution for Java projects is not to write your own stopwatch or timer classes, but just use the org.apache.commons.lang.time.StopWatch class that is part of Apache Commons Lang.

如果目的是简单地将粗糙的计时信息打印到程序日志中,那么Java项目的简单解决方案不是编写自己的秒表或计时器类,而是使用org.apache.common . Lang. time. stopwatch类,这是Apache Commons Lang的一部分。

final StopWatch stopwatch = new StopWatch();
stopwatch.start();
LOGGER.debug("Starting long calculations: {}", stopwatch);
...
LOGGER.debug("Time after key part of calcuation: {}", stopwatch);
...
LOGGER.debug("Finished calculating {}", stopwatch);

#5


13  

New Technology In Java 8+

We have new technology for this now built into Java 8 and later, the java.time framework.

我们在Java 8和后来的Java中已经有了新的技术。时间框架。

java.time

The java.time framework is defined by JSR 310, inspired by the highly successful Joda-Time project, extended by the ThreeTen-Extra project, and described in the Oracle Tutorial.

java。时间框架由JSR 310定义,灵感来自于非常成功的Joda-Time项目,由三个额外的项目扩展,并在Oracle教程中进行了描述。

The old date-time classes such as java.util.Date/.Calendar bundled with the earliest versions of Java have proven to be poorly designed, confusing, and troublesome. They are supplanted by the java.time classes.

旧的日期时间类,如java.util.Date/。与Java早期版本捆绑在一起的日历被证明设计糟糕、混乱且麻烦。它们被java取代了。时间类。

Resolution

Other answers discuss resolution.

其他答案讨论决议。

The java.time classes have nanosecond resolution, up to nine digits of a decimal fraction of a second. For example, 2016-03-12T04:29:39.123456789Z.

java。时间类有纳秒的分辨率,高达九位数的秒。例如,2016 - 03 - 12 - t04:29:39.123456789z。

Both the old java.util.Date/.Calendar classes and the Joda-Time classes have millisecond resolution (3 digits of fraction). For example, 2016-03-12T04:29:39.123Z.

*ava.util.Date /。日历类和Joda-Time类有毫秒级的分辨率(3位数的分数)。例如,2016 - 03 - 12 - t04:29:39.123z。

In Java 8, the current moment is fetched with up to only millisecond resolution because of a legacy issue. In Java 9 and later, the current time can be determined up to nanosecond resolution provided your computer’s hardware clock runs so finely.

在Java 8中,由于遗留问题,当前时刻的分辨率最高只有毫秒。在Java 9和以后的版本中,如果您的计算机的硬件时钟运行得非常好,那么当前的时间可以确定到纳秒的分辨率。

Time-Of-Day

If you truly want to work with only the time-of-day lacking any date or time zone, use the LocalTime class.

如果您真的想只使用一天中没有任何日期或时区的时间,请使用LocalTime类。

LocalTime sooner = LocalTime.of ( 17, 00 );
LocalTime later = LocalTime.of ( 19, 00 );

A Duration represents a span of time it terms of a count of seconds plus nanoseconds.

持续时间表示持续时间的跨度,即秒数加上纳秒数。

Duration duration = Duration.between ( sooner, later );

Dump to console.

转储到控制台。

System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );

sooner: 17:00 | later: 19:00 | duration: PT2H

更早:17:00 |稍后:19:00 |时间:PT2H。

ISO 8601

Notice the default output of Duration::toString is in standard ISO 8601 format. In this format, the P marks the beginning (as in 'Period'), and the T separates any years-months-days portion from the hours-minutes-seconds portion.

注意默认的持续时间输出:::toString是标准ISO 8601格式。在这种格式中,P表示开始(如“句点”),T将任何年、月、日部分与小时、分钟、秒部分分开。

Crossing Midnight

Unfortunately, working with time-of-day only gets tricky when you wrap around the clock crossing midnight. The LocalTime class handles this by assuming you want to go backwards to an earlier point in the day.

不幸的是,只有当你在午夜完成一天的工作时,工作才会变得棘手。LocalTime类通过假设您想要回溯到当天早些时候的某个点来处理这个问题。

Using the same code as above but going from 23:00 to 01:00 results in a negative twenty-two hours (PT-22H).

使用与上面相同的代码,但是从23:00到01:00将导致负22小时(PT-22H)。

LocalTime sooner = LocalTime.of ( 23, 0 );
LocalTime later = LocalTime.of ( 1, 0 );

sooner: 23:00 | later: 01:00 | duration: PT-22H

稍后23:00 | 01:00 |持续时间:PT-22H

Date-Time

If you intend to cross midnight, it probably makes sense for you to be working with date-time values rather than time-of-day-only values.

如果您打算跨越午夜,那么使用日期-时间值而不是只使用一天时间值可能是有意义的。

Time Zone

Time zone is crucial to dates. So we specify three items: (1) the desired date, (2) desired time-of-day, and (3) the time zone as a context by which to interpret that date and time. Here we arbitrarily choose the time zone of the Montréal area.

时区对日期至关重要。因此,我们指定了三个项目:(1)期望的日期;(2)期望的一天时间;(3)时区作为解释日期和时间的上下文。这里我们任意选择蒙特利尔地区的时区。

If you define the date by only an offset-from-UTC, use a ZoneOffset with a OffsetDateTime. If you have a full time zone (offset plus rules for handling anomalies such as Daylight Saving Time), use a ZoneId with a ZonedDateTime.

如果您仅通过一个offset-from-UTC定义日期,则使用带有OffsetDateTime的ZoneOffset。如果您有一个完整的时区(偏移量加上处理异常的规则,如夏令时),请使用带ZonedDateTime的ZoneId。

LocalDate localDate = LocalDate.of ( 2016, 1, 23 );
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime sooner = ZonedDateTime.of ( localDate, LocalTime.of ( 23, 0 ), zoneId );

We specify the later time as next day at 1:00 AM.

我们把晚一点的时间定为第二天凌晨一点。

ZonedDateTime later = ZonedDateTime.of ( localDate.plusDays ( 1 ), LocalTime.of ( 1, 0 ), zoneId );

We calculate the Duration in the same manner as seen above. Now we get the two hours expected by this Question.

我们按照上面看到的方式计算持续时间。现在我们得到了这个问题所期望的两个小时。

Duration duration = Duration.between ( sooner, later );

Dump to console.

转储到控制台。

System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );

sooner: 2016-01-23T23:00-05:00[America/Montreal] | later: 2016-01-24T01:00-05:00[America/Montreal] | duration: PT2H

早:2016-01-23T23:00-05:00[美国/蒙特利尔]|后:2016-01-24T01:00-05:00[美国/蒙特利尔]|持续时间:PT2H

Daylight Saving Time

If the date-times at hand had involved Daylight Saving Time (DST) or other such anomaly, the java.time classes would adjust as needed. Read class doc for details.

如果当前的日期时间涉及夏令时(DST)或其他类似的异常,则使用java。时间类将根据需要进行调整。详细信息请阅读class doc。


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java。time框架被构建到Java 8以及以后的版本中。这些类取代了麻烦的旧遗留日期时间类(如java.util)。日期,日历,& SimpleDateFormat。

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

现在处于维护模式的Joda-Time项目建议迁移到java。时间类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle教程。和搜索堆栈溢出为许多例子和解释。规范是JSR 310。

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

你可以交换java。时间对象直接与您的数据库。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java.sql。*类。

Where to obtain the java.time classes?

在哪里获得java。时间类?

  • Java SE 8, Java SE 9, Java SE 10, and later
    • Built-in.
    • 内置的。
    • Part of the standard Java API with a bundled implementation.
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9 adds some minor features and fixes.
    • Java 9添加了一些次要的特性和修复。
  • Java SE 8, Java SE 9, Java SE 10,以及后来的内置。带有捆绑实现的标准Java API的一部分。Java 9添加了一些次要的特性和修复。
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • 大部分java。时间功能在三个回端移植到Java 6和7。
  • Java SE 6和Java SE 7大部分的Java。时间功能在三个回端移植到Java 6和7。
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • java的Android bundle实现的后续版本。时间类。
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
    • 对于早期的Android (<26), ThreeTenABP项目适用于three - backport(如上所述)。看到如何使用ThreeTenABP ....
  • Android后期版本的java捆绑包实现。时间类。对于早期的Android (<26), ThreeTenABP项目适用于three - backport(如上所述)。看到如何使用ThreeTenABP ....

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

三个额外的项目扩展了java。时间和额外的类。这个项目是java.time未来可能增加的一个试验场。您可以在这里找到一些有用的课程,如间隔、年周、年季等。

#6


7  

Java provides the static method System.currentTimeMillis(). And that's returning a long value, so it's a good reference. A lot of other classes accept a 'timeInMillis' parameter which is long as well.

Java提供了静态方法System.currentTimeMillis()。这是返回一个很长的值,这是一个很好的参考。许多其他类都接受“timeInMillis”参数,该参数也很长。

And a lot of people find it easier to use the Joda Time library to do calculations on dates and times.

很多人发现使用Joda Time库来计算日期和时间更容易。

#7


6  

Which types to use in order to accomplish this in Java?

为了在Java中实现这一点,需要使用哪些类型?

Answer: long

答:长

public class Stream {
    public long startTime;
    public long endTime;

    public long getDuration() {
        return endTime - startTime;
    }
    // I  would add
    public void start() {
        startTime = System.currentTimeMillis();
    }
    public void stop() {
         endTime = System.currentTimeMillis();
     }
}

Usage:

用法:

  Stream s = .... 

  s.start();

  // do something for a while 

  s.stop();

  s.getDuration(); // gives the elapsed time in milliseconds. 

That's my direct answer for your first question.

这就是我对你第一个问题的直接回答。

For the last "note" I would suggest you to use Joda Time. It contains an interval class suitable for what you need.

最后,我建议你使用Joda Time。它包含一个适合您需要的interval类。

#8


6  

It is worth noting that

值得注意的是。

  • System.currentTimeMillis() has only millisecond accuracy at best. At worth its can be 16 ms on some windows systems. It has a lower cost that alternatives < 200 ns.
  • currenttimemillis()充其量只有毫秒级的准确度。在某些windows系统上,它可以值16毫秒。它的成本低于200纳秒。
  • System.nanoTime() is only micro-second accurate on most systems and can jump on windows systems by 100 microseconds (i.e sometimes it not as accurate as it appears)
  • System.nanoTime()在大多数系统中都只有微秒的准确率,并且可以在windows系统中跳转100微秒(i)。e有时它不像看上去的那么准确)
  • Calendar is a very expensive way to calculate time. (i can think of apart from XMLGregorianCalendar) Sometimes its the most appropriate solution but be aware you should only time long intervals.
  • 日历是计算时间的一种非常昂贵的方法。(除了XMLGregorianCalendar)有时这是最合适的解决方案,但要注意,您应该只使用长时间间隔。

#9


3  

If you are writing an application that must deal with durations of time, then please take a look at Joda-Time which has class specifically for handling Durations, Intervals, and Periods. Your getDuration() method looks like it could return a Joda-Time Interval:

如果您正在编写一个必须处理时间间隔的应用程序,那么请查看Joda-Time,它有专门用于处理时间间隔和周期的类。您的getDuration()方法看起来可以返回一个Joda-Time间隔:

DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);

public Interval getInterval() {
    Interval interval = new Interval(start, end);
}

#10


2  

If you prefer using Java's Calendar API you can try this,

如果你喜欢使用Java的日历API,你可以试试这个,

Date startingTime = Calendar.getInstance().getTime();
//later on
Date now = Calendar.getInstance().getTime();
long timeElapsed = now.getTime() - startingTime.getTime();

#11


1  

If you're getting your timestamps from System.currentTimeMillis(), then your time variables should be longs.

如果您正在从System.currentTimeMillis()获取时间戳,那么您的时间变量应该很长。

#12


1  

Byte Stream Reader Elapsed Time for 23.7 MB is 96 secs

import java.io.*;
import java.io.IOException;
import java.util.Scanner;

class ElaspedTimetoCopyAFileUsingByteStream
{

    private long startTime = 0;
    private long stopTime = 0;
    private boolean running = false;


    public void start() 
    {
        this.startTime = System.currentTimeMillis();
        this.running = true;
    }


    public void stop() 
    {
        this.stopTime = System.currentTimeMillis();
        this.running = false;
    }



    public long getElapsedTime() 
    {
        long elapsed;
        if (running) {
             elapsed = (System.currentTimeMillis() - startTime);
        }
        else {
            elapsed = (stopTime - startTime);
        }
        return elapsed;
    }



    public long getElapsedTimeSecs()                 
    {
        long elapsed;
        if (running) 
        {
            elapsed = ((System.currentTimeMillis() - startTime) / 1000);
        }
        else
        {
            elapsed = ((stopTime - startTime) / 1000);
        }
        return elapsed;
    }





    public static void main(String[] args) throws IOException
    {
        ElaspedTimetoCopyAFileUsingByteStream  s = new ElaspedTimetoCopyAFileUsingByteStream();
        s.start();

        FileInputStream in = null;
        FileOutputStream out = null;

      try {
         in = new FileInputStream("vowels.txt");   // 23.7  MB File
         out = new FileOutputStream("output.txt");

         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }



        s.stop();
        System.out.println("elapsed time in seconds: " + s.getElapsedTimeSecs());
    }
}

[Elapsed Time for Byte Stream Reader][1]

**Character Stream Reader Elapsed Time for 23.7 MB is 3 secs**

import java.io.*;
import java.io.IOException;
import java.util.Scanner;

class ElaspedTimetoCopyAFileUsingCharacterStream
{

    private long startTime = 0;
    private long stopTime = 0;
    private boolean running = false;


    public void start() 
    {
        this.startTime = System.currentTimeMillis();
        this.running = true;
    }


    public void stop() 
    {
        this.stopTime = System.currentTimeMillis();
        this.running = false;
    }



    public long getElapsedTime() 
    {
        long elapsed;
        if (running) {
             elapsed = (System.currentTimeMillis() - startTime);
        }
        else {
            elapsed = (stopTime - startTime);
        }
        return elapsed;
    }



    public long getElapsedTimeSecs()                 
    {
        long elapsed;
        if (running) 
        {
            elapsed = ((System.currentTimeMillis() - startTime) / 1000);
        }
        else
        {
            elapsed = ((stopTime - startTime) / 1000);
        }
        return elapsed;
    }





    public static void main(String[] args) throws IOException
    {
        ElaspedTimetoCopyAFileUsingCharacterStream  s = new ElaspedTimetoCopyAFileUsingCharacterStream();
        s.start();

         FileReader in = null;                // CharacterStream Reader
      FileWriter out = null;

      try {
         in = new FileReader("vowels.txt");    // 23.7 MB
         out = new FileWriter("output.txt");

         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }

              s.stop();
        System.out.println("elapsed time in seconds: " + s.getElapsedTimeSecs());
    }
}


[Elapsed Time for Character Stream Reader][2]


  [1]: https://i.stack.imgur.com/hYo8y.png
  [2]: https://i.stack.imgur.com/xPjCK.png

#13


0  

i found this code to be useful when timing things:

我发现这个代码在计时时很有用:

public class Et {
    public Et() {
    reset();
    }
    public void reset() {
    t0=System.nanoTime();
    }
    public long t0() {
        return t0;
    }
    public long dt() {
        return System.nanoTime()-t0();
    }
    public double etms() {
    return etms(dt());
    }
    @Override public String toString() {
        return etms()+" ms.";
    }
    public static double etms(long dt) {
        return dt/1000000.; // 1_000_000. breaks cobertura
    }
    private Long t0;
}

#14


0  

Use this:

用这个:

SimpleDateFormat format = new SimpleDateFormat("HH:mm");

Date d1 = format.parse(strStartTime);
Date d2 = format.parse(strEndTime);

long diff = d2.getTime() - d1.getTime();
long diffSeconds,diffMinutes,diffHours;

if (diff > 0) {
diffSeconds = diff / 1000 % 60;
diffMinutes = diff / (60 * 1000) % 60;
diffHours = diff / (60 * 60 * 1000);
}
else{
long diffpos = (24*((60 * 60 * 1000))) + diff;
diffSeconds = diffpos / 1000 % 60;
diffMinutes = diffpos / (60 * 1000) % 60;
diffHours = (diffpos / (60 * 60 * 1000));
}

(Also it is important that for example if the startTime it's 23:00 and endTime 1:00 to get a duration of 2:00.)

(同样重要的是,如果开始时间是23:00,结束时间是1:00,则持续时间是2:00。)

the "else" part can get it correct

“else”部分可以得到正确的答案

#15


0  

I built a formatting function based on stuff I stole off SO. I needed a way of "profiling" stuff in log messages, so I needed a fixed length duration message.

我构建了一个基于我偷来的东西的格式化函数。我需要一种在日志消息中“分析”内容的方法,所以我需要一个固定长度的持续时间消息。

public static String GetElapsed(long aInitialTime, long aEndTime, boolean aIncludeMillis)
{
  StringBuffer elapsed = new StringBuffer();

  Map<String, Long> units = new HashMap<String, Long>();

  long milliseconds = aEndTime - aInitialTime;

  long seconds = milliseconds / 1000;
  long minutes = milliseconds / (60 * 1000);
  long hours = milliseconds / (60 * 60 * 1000);
  long days = milliseconds / (24 * 60 * 60 * 1000);

  units.put("milliseconds", milliseconds);
  units.put("seconds", seconds);
  units.put("minutes", minutes);
  units.put("hours", hours);
  units.put("days", days);

  if (days > 0)
  {
    long leftoverHours = hours % 24;
    units.put("hours", leftoverHours);
  }

  if (hours > 0)
  {
    long leftoeverMinutes = minutes % 60;
    units.put("minutes", leftoeverMinutes);
  }

  if (minutes > 0)
  {
    long leftoverSeconds = seconds % 60;
    units.put("seconds", leftoverSeconds);
  }

  if (seconds > 0)
  {
    long leftoverMilliseconds = milliseconds % 1000;
    units.put("milliseconds", leftoverMilliseconds);
  }

  elapsed.append(PrependZeroIfNeeded(units.get("days")) + " days ")
      .append(PrependZeroIfNeeded(units.get("hours")) + " hours ")
      .append(PrependZeroIfNeeded(units.get("minutes")) + " minutes ")
      .append(PrependZeroIfNeeded(units.get("seconds")) + " seconds ")
      .append(PrependZeroIfNeeded(units.get("milliseconds")) + " ms");

  return elapsed.toString();

}

private static String PrependZeroIfNeeded(long aValue)
{
  return aValue < 10 ? "0" + aValue : Long.toString(aValue);
}

And a test class:

和一个测试类:

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import junit.framework.TestCase;

public class TimeUtilsTest extends TestCase
{

  public void testGetElapsed()
  {
    long start = System.currentTimeMillis();
    GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance();
    calendar.setTime(new Date(start));

    calendar.add(Calendar.MILLISECOND, 610);
    calendar.add(Calendar.SECOND, 35);
    calendar.add(Calendar.MINUTE, 5);
    calendar.add(Calendar.DAY_OF_YEAR, 5);

    long end = calendar.getTimeInMillis();

    assertEquals("05 days 00 hours 05 minutes 35 seconds 610 ms", TimeUtils.GetElapsed(start, end, true));

  }

}