我是java的初学者。我创建了一个用于追踪工作时间的应用程序
有2个功能1.启动时间和2.停止时间,当用户我必须计算时间并给出它们之间的差异并存储它。
我已经尝试了所有的搜索引擎,但我没有找到合适的词来找到它
但问题是,如果用户启动计时器,然后用更多时间更改系统时间更新,那么我的输出是错误的
现在我要为这个问题做些什么?有没有办法检测系统时间变化?
答案 0 :(得分:0)
您可以使用 google-guava 库类Stopwatch
例子
Stopwatch s = new Stopwatch().start();
...
long passedMillis = s.stop().elapsedMillis();
如果用户更改系统时间,按预期工作。
Maven依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>11.0.2</version>
<type>jar</type>
</dependency>
或者你可以使用 apache-commons lib class StopWatch 例子
StopWatch s = new StopWatch();
s.start();
...
s.stop();
long passedMillis = s.getTime();
Maven依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
答案 1 :(得分:0)
您有两种方法可以解决您的问题:
1)防止系统时间变化:
如果计算机是由系统管理员控制的公司计算机且用户没有管理员权限,则这很容易。 由于更改时间需要一些高级用户权限,因此用户将无法更改系统时间。可以在计算中考虑“正式”时间的变化,因为它是计划好的并且知道何时发生。
2)监控系统时间: 您可以通过将系统时间与先前读取系统时间进行比较的线程来监视系统时间更改。如果突然发生意外变化,您可以检测到用户是在作弊。
在同一个帖子中,你可以拥有某种“瘫痪时间”计数器,每秒都会更新一个计数器。这样,无论用户是否更改时间,您都将更新“耗尽时间计数器”并使用它来计算任务持续时间而非系统时间。
答案 2 :(得分:0)
但问题是如果用户启动计时器然后更改系统 用更多时间更新时间然后输出错误。
在linux下,您可以安全地使用System.getNanoTime()
,因为它使用CLOCK_MONOTONIC
作为时钟源。这只有在系统在开始时间和结束时间之间没有重新启动时才有效。
CLOCK_MONOTONIC
是一个无法更改的时钟源。系统启动时会将其初始化为任意值。该时钟只会以恒定的方式递增。没有跳跃。
测量时间非常有用,因为它与系统的挂壁时间(您在电脑的时钟上看到的时间)无关,而且非常准确。
我刚刚看了一下openjdk-7-b147的来源。
在hotspot\src\os\linux\vm\os_linux.cpp
jlong os::javaTimeNanos() {
if (Linux::supports_monotonic_clock()) {
struct timespec tp;
int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp);
assert(status == 0, "gettime error");
jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
return result;
} else {
timeval time;
int status = gettimeofday(&time, NULL);
assert(status != -1, "linux error");
jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
return 1000 * usecs;
}
}
<强> CLOCK_MONOTONIC 强>
无法设置的时钟,表示一些时间以来的单调时间 未说明的起点。
我不知道它在Windows上是如何工作的,但我猜测使用的时钟源也不依赖于挂钟。
This blog post可能会有所帮助。