我想要这样的东西:
public class Stream
{
public startTime;
public endTime;
public getDuration()
{
return startTime - endTime;
}
}
Run Code Online (Sandbox Code Playgroud)
同样重要的是,例如,如果startTime为23:00,endTime为1:00,则持续时间为2:00.
在Java中使用哪些类型来实现这一目的?
Kev*_*ion 631
不幸的是,迄今为止发布的十个答案中没有一个是完全正确的.
如果您正在测量经过的时间,并且您希望它是正确的,则必须使用System.nanoTime()
.你不能使用System.currentTimeMillis()
,除非你不介意你的结果是错误的.
目的nanoTime
是测量经过时间,目的currentTimeMillis
是测量挂钟时间.你不能将它用于其他目的.原因是没有计算机的时钟是完美的; 它总是漂移,偶尔需要纠正.这种修正可能是手动发生的,或者在大多数机器的情况下,有一个运行的过程并不断对系统时钟("挂钟")进行小的修正.这些往往经常发生.只要有闰秒,就会发生另一次这样的修正.
由于其nanoTime
目的是测量经过的时间,因此不受任何这些小修正的影响.这是你想要使用的.目前正在进行的任何时间currentTimeMillis
都将被取消 - 甚至可能是负面的.
你可能会说,"这听起来不像真的那么重要",我说,也许不是,但总的来说,不正确的代码比错误的代码更好吗?此外,nanoTime
无论如何都要更短.
以前发布的关于nanoTime
通常只有微秒精度的免责声明是有效的.根据情况(也可能是另一个),调用它可能需要超过一微秒才能完成,所以不要指望正确地计算非常小的时间间隔.
Pas*_*ent 208
在Java中使用哪些类型来实现这一目的?
简短的回答是long
.现在,更多关于如何衡量......
实现这一目标的"传统"方式确实可以使用System.currentTimeMillis()
:
long startTime = System.currentTimeMillis();
// ... do something ...
long estimatedTime = System.currentTimeMillis() - startTime;
Run Code Online (Sandbox Code Playgroud)
请注意,Commons Lang有一个StopWatch类,可用于测量执行时间(以毫秒为单位).它有方法的方法,如split()
,suspend()
,resume()
,等,允许采取的措施在执行的不同点,因此您可能觉得方便.看看它.
System.nanoTime()
如果您正在寻找非常精确的经过时间测量,您可能更愿意使用.从它的javadoc:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用JAMon,这是一种为start()和stop()方法之间的任何代码收集统计数据(执行时间,命中数,平均执行时间,最小值,最大值等)的工具.下面是一个非常简单的例子:
import com.jamonapi.*;
...
Monitor mon=MonitorFactory.start("myFirstMonitor");
...Code Being Timed...
mon.stop();
Run Code Online (Sandbox Code Playgroud)
查看www.javaperformancetunning.com上的这篇文章,获得精彩的介绍.
最后,如果您不希望使用这些测量值混乱代码(或者如果您无法更改现有代码),那么AOP将是一个完美的武器.我不打算深入讨论这个问题,但至少我想提一下.
下面是使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
切入点定义可以很容易地适应于基于类名,包名,方法名或这些的任何组合来监视任何方法.测量确实是AOP的完美用例.
GHa*_*Had 35
你的新班级:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
TimeWatch watch = TimeWatch.start();
// do something
long passedTimeInMs = watch.time();
long passedTimeInSeconds = watch.time(TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
之后,经过的时间可以转换为您喜欢的任何格式,例如使用日历
格雷茨,GHad
Dav*_*iss 20
如果目的是简单地将粗略的计时信息打印到程序日志中,那么Java项目的简单解决方案不是编写自己的秒表或计时器类,而只是使用org.apache.commons.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);
Run Code Online (Sandbox Code Playgroud)
Bas*_*que 16
例如,如果startTime是23:00,endTime是1:00,则持续时间为2:00.
不可能.如果您只有时间,那么时钟会在午夜停止.如果没有日期的背景,我们怎么知道你是在第二天,下周还是下一个十年的凌晨1点?
所以从晚上11点到凌晨1点意味着在22小时内向后移动,逆时针运行时钟指针.看下面的结果,负二十二小时.
Duration.between( // Represent a span of time a total number of seconds plus a fractional second in nanoseconds.
LocalTime.of( 23 , 0 ) , // A time-of-day without a date and without a time zone.
LocalTime.of( 1 , 0 ) // A time-of-day clock stops at midnight. So getting to 1 AM from 11 PM means going backwards 22 hours.
) // Return a `Duration` object.
.toString() // Generate a `String` representing this span of time using standard ISO 8601 format: PnYnMnDTnHnMnS
Run Code Online (Sandbox Code Playgroud)
PT-22H
跨越午夜需要更大的日期背景以及时间(见下文).
如何衡量Java中的时间?
Instant.now()
.Duration.between
.Duration
对象中,通过调用各种to…Part
方法,以纳秒为单位提取24小时的天,小时,分钟,秒和小数秒.toString
生成一个String
在标准ISO 8601格式的PnYnMnDTnHnMnS
.示例代码,使用一对Instant
对象.
Duration.between( // Represent a span of time a total number of seconds plus a fractional second in nanoseconds.
then , // Some other `Instant` object, captured earlier with `Instant.now()`.
Instant.now() // Capture the current moment in UTC with a resolution as fine as nanoseconds, depending on the limits of your host computer hardware clock and operating system. Generally you will get current moment in microseconds (six decimal digits of fractional second) in Java 9, 10, and 11, but only milliseconds in Java 8.
) // Return a `Duration` object.
.toString() // Generate a `String` representing this span of time using standard ISO 8601 format: PnYnMnDTnHnMnS
Run Code Online (Sandbox Code Playgroud)
PT3M27.602197S
我们现在已经在Java 8及更高版本java.time框架中构建了新技术.
java.time框架由JSR 310定义,受到非常成功的Joda-Time项目的启发,该项目由ThreeTen-Extra项目扩展,并在Oracle Tutorial中进行了描述.
与最早版本的Java捆绑在一起的旧日期时间类(如java.util.Date/.Calendar)已被证明设计不当,令人困惑且麻烦.它们被java.time类取代.
其他答案讨论决议.
java.time类具有纳秒分辨率,最高可达一位小数的九位数.例如,2016-03-12T04:29:39.123456789Z
.
旧的java.util.Date/.Calendar类和Joda-Time类都具有毫秒分辨率(分数的3位数).例如,2016-03-12T04:29:39.123Z
.
在Java 8中,由于遗留问题,当前时刻的分辨率最高只有毫秒.在Java 9及更高版本中,只要计算机的硬件时钟运行得非常精细,当前时间就可以确定为纳秒分辨率.
如果您真的只想使用缺少任何日期或时区的时间,请使用该LocalTime
课程.
LocalTime sooner = LocalTime.of ( 17, 00 );
LocalTime later = LocalTime.of ( 19, 00 );
Run Code Online (Sandbox Code Playgroud)
A Duration
表示计数秒加上纳秒的时间跨度.
Duration duration = Duration.between ( sooner, later );
Run Code Online (Sandbox Code Playgroud)
转储到控制台.
System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );
Run Code Online (Sandbox Code Playgroud)
早点:17:00 | 晚点:19:00 | 持续时间:PT2H
请注意,默认输出采用Duration::toString
标准ISO 8601格式.在这种格式中,P
标记开头(如'期间'),并将T
任何年 - 月 - 日部分与小时 - 分 - 秒部分分开.
不幸的是,当您绕过午夜的时钟时,处理时间只会变得棘手.该LocalTime
班由假设要倒退到当天更早一点处理这个.
使用相同的代码如上但是从去23:00
到01:00
在负22小时结果(PT-22H
).
LocalTime sooner = LocalTime.of ( 23, 0 );
LocalTime later = LocalTime.of ( 1, 0 );
Run Code Online (Sandbox Code Playgroud)
早点:23:00 | 之后:01:00 持续时间:PT-22H
如果您打算跨越午夜,那么使用日期时间值而不是仅限时间的值可能是有意义的.
时区对日期至关重要.因此,我们指定三个项目:(1)期望日期,(2)期望的时间,以及(3)时区作为解释该日期和时间的上下文.在这里,我们任意选择蒙特利尔地区的时区.
如果仅通过UTC的偏移量定义日期,请使用ZoneOffset
带a的a OffsetDateTime
.如果您有一个完整的时区(偏移量加上处理夏令时等异常的规则),请使用ZoneId
a ZonedDateTime
.
LocalDate localDate = LocalDate.of ( 2016, 1, 23 );
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime sooner = ZonedDateTime.of ( localDate, LocalTime.of ( 23, 0 ), zoneId );
Run Code Online (Sandbox Code Playgroud)
我们将下一个时间指定为次日凌晨1:00.
ZonedDateTime later = ZonedDateTime.of ( localDate.plusDays ( 1 ), LocalTime.of ( 1, 0 ), zoneId );
Run Code Online (Sandbox Code Playgroud)
我们Duration
以与上面相同的方式计算.现在我们得到了这个问题预计的两个小时.
Duration duration = Duration.between ( sooner, later );
Run Code Online (Sandbox Code Playgroud)
转储到控制台.
System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );
Run Code Online (Sandbox Code Playgroud)
更快:2016-01-23T23:00-05:00 [美国/蒙特利尔] | 之后:2016-01-24T01:00-05:00 [美国/蒙特利尔] | 持续时间:PT2H
如果手头的日期时间涉及夏令时(DST)或其他此类异常,则java.time类将根据需要进行调整.阅读课程文档了解详情.
该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date
,Calendar
,和SimpleDateFormat
.
现在处于维护模式的Joda-Time项目建议迁移到java.time类.
要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.
您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*
从哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval
,YearWeek
,YearQuarter
,和更多.
值得一提的是
在Java中使用哪些类型来实现这一目的?
答:很久
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();
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
Stream s = ....
s.start();
// do something for a while
s.stop();
s.getDuration(); // gives the elapsed time in milliseconds.
Run Code Online (Sandbox Code Playgroud)
这是我对你的第一个问题的直接回答.
对于最后一个"注释",我建议你使用Joda Time.它包含适合您需要的间隔类.
归档时间: |
|
查看次数: |
406255 次 |
最近记录: |