/**
*
* 获取系统运行期间,永远增长时间搓,可以使用年限146.
* 每次重新启动运行后,都从0开始,能够保证在运行期间,一直自增,不受系统时间被回拨(回退,前进)的影响。
* 使用场景举例:
* 有人提了雪花算法如何保证服务器时间回拨了还保证生成的id递增的问题,其实想想也很简单。
* 1、系统基准时间商定: 系统在初始化生成器时,寻找初始化基准时间,先去已经启动的其它任何一个节点获取它们当前记录的时间搓,若没有启动的节点,那么取数据库中当前最大ID进行分析提取,提取得到的时间搓和数据库当前时间搓比较去最大值。
* 2、基准时间获取后,在通过基准时间与{@link #currentTimeMillis()}的和得到算法的时间位。
* 后续依然采用现在的算法,只是时间位使用基准时间搓与jvm运行时间的结合。
* 保证算法时间位不依赖本地时间,不怕服务器时间的调整。
* 大家公用一样的方式获取时间搓,保证大家要错一起错,至少保证所有节点的递增性
*
* @author pdy
*
*/
public class SelfTime {
/**
* 一秒对应多少纳秒
*/
private final static long SECOND_NANO = 1000000000;
/**
* 一毫秒对应多少纳秒
*/
private final static long MILLIS_NANO = 1000000;
/**
* 基准纳秒时间
*/
private long baseTimeNano;
public SelfTime() {
baseTimeNano = System.nanoTime();
}
/**
* 获取自增的纳秒时间,不精确,慎用
* @return 纳秒
*/
public long currentTimeNano() {
long curr = System.nanoTime();
if(baseTimeNano <= curr) {
return curr - baseTimeNano;
} else {
//System.nanoTime()出现了溢出,需要将溢出部分加入 基本不可能出现的
return (curr - Long.MIN_VALUE + 1) + (Long.MAX_VALUE - baseTimeNano);
}
}
/**
* 获取自增的毫秒时间
* @return 毫秒
*/
public long currentTimeMillis() {
return currentTimeNano()/MILLIS_NANO;
}
/**
* 获取自增的秒时间
* @return 秒
*/
public long currentTimeSecond() {
return currentTimeNano()/SECOND_NANO;
}
}