package org.springside.modules.utils.time;
import java.util.Date;
/**
* 日期提供者, 使用它而不是直接取得系统时间, 方便测试.
*
* 平时使用DEFAULT,测试时替换为DummyClock,可准确控制时间变化而不用Thread.sleep()等待时间流逝.
*
* @author calvin
*/
public class ClockUtil {
private static Clock INSTANCE = new DefaultClock();
/**
* 计算流逝的时间
*/
public static long elapsedTime(long beginTime) {
return currentTimeMillis() - beginTime;
}
/**
* 切换为DummyClock,使用系统时间为初始时间, 单个测试完成后需要调用useDefaultClock()切换回去.
*/
public static synchronized DummyClock useDummyClock() {
INSTANCE = new DummyClock();
return (DummyClock) INSTANCE;
}
/**
* 切换为DummyClock,单个测试完成后需要调用useDefaultClock()切换回去.
*/
public static synchronized DummyClock useDummyClock(long timeStampMills) {
INSTANCE = new DummyClock(timeStampMills);
return (DummyClock) INSTANCE;
}
/**
* 切换为DummyClock,单个测试完成后需要调用useDefaultClock()切换回去.
*/
public static synchronized DummyClock useDummyClock(Date date) {
INSTANCE = new DummyClock(date);
return (DummyClock) INSTANCE;
}
/**
* 重置为默认Clock
*/
public static synchronized void useDefaultClock() {
INSTANCE = new DefaultClock();
}
/**
* 系统当前时间
*/
public static Date currentDate() {
return INSTANCE.currentDate();
}
/**
* 系统当前时间戳
*/
public static long currentTimeMillis() {
return INSTANCE.currentTimeMillis();
}
/**
* 操作系统启动到现在的纳秒数,与系统时间是完全独立的两个时间体系
*/
public static long nanoTime() {
return INSTANCE.nanoTime();
}
public interface Clock {
/**
* 系统当前时间
*/
Date currentDate();
/**
* 系统当前时间戳
*/
long currentTimeMillis();
/**
* 操作系统启动到现在的纳秒数,与系统时间是完全独立的两个时间体系
*/
long nanoTime();
}
/**
* 默认时间提供者,返回当前的时间,线程安全。
*/
public static class DefaultClock implements Clock {
@Override
public Date currentDate() {
return new Date();
}
@Override
public long currentTimeMillis() {
return System.currentTimeMillis();
}
@Override
public long nanoTime() {
return System.nanoTime();
}
}
/**
* 可配置的时间提供者,用于测试.
*/
public static class DummyClock implements Clock {
private long time;
private long nanoTme;
public DummyClock() {
this(System.currentTimeMillis());
}
public DummyClock(Date date) {
this(date.getTime());
}
public DummyClock(long time) {
this.time = time;
this.nanoTme = System.nanoTime();
}
@Override
public Date currentDate() {
return new Date(time);
}
@Override
public long currentTimeMillis() {
return time;
}
/**
* 获取nanotime
*/
@Override
public long nanoTime() {
return nanoTme;
}
/**
* 重新设置日期.
*/
public void updateNow(Date newDate) {
time = newDate.getTime();
}
/**
* 重新设置时间.
*/
public void updateNow(long newTime) {
this.time = newTime;
}
/**
* 滚动时间.
*/
public void increaseTime(int millis) {
time += millis;
}
/**
* 滚动时间.
*/
public void decreaseTime(int millis) {
time -= millis;
}
/**
* 设置nanotime.
*/
public void setNanoTime(long nanoTime) {
this.nanoTme = nanoTime;
}
}
}