forked from KNEMC/KLALB
KLALB V3.6.0 写了一半
This commit is contained in:
@@ -17,24 +17,26 @@ public class HighAccuracyClock {
|
||||
|
||||
private final long initialCPUNanoTime;
|
||||
private final Long128 initialSystemNanoTime;
|
||||
private volatile AtomicLong baseCPUNanoTime=new AtomicLong();
|
||||
private volatile long baseCPUNanoTime;
|
||||
private volatile Long128 baseSystemNanoTime;
|
||||
|
||||
private volatile long frequency=1000000000;//1000015000
|
||||
|
||||
private volatile long frequency2=frequency*0xffffffffL/1000000000L;
|
||||
|
||||
private ReentrantLock lock=new ReentrantLock();
|
||||
|
||||
private static final Long128 NANOS_PER_MILLIS = Long128.valueOf(TimeUnit.MILLISECONDS.toNanos(1));
|
||||
|
||||
|
||||
private static final Long128 NANOS_PER_SECONDS = Long128.valueOf(TimeUnit.SECONDS.toNanos(1));
|
||||
public static final HighAccuracyClock SYSTEM_CLOCK = new HighAccuracyClock();
|
||||
|
||||
|
||||
public HighAccuracyClock() {
|
||||
this.initialSystemNanoTime =Long128.valueOf( System.currentTimeMillis() ).multiply(NANOS_PER_MILLIS);
|
||||
this.initialCPUNanoTime = System.nanoTime();
|
||||
this.baseSystemNanoTime=initialSystemNanoTime;
|
||||
this.baseCPUNanoTime.set(initialCPUNanoTime);
|
||||
this.baseCPUNanoTime=initialCPUNanoTime;
|
||||
}
|
||||
|
||||
public long getFrequency() {
|
||||
@@ -45,9 +47,11 @@ public class HighAccuracyClock {
|
||||
lock.lock();
|
||||
try {
|
||||
long curr=System.nanoTime();
|
||||
long nanoela=curr-baseCPUNanoTime.getAndSet(curr);
|
||||
long nanoela=curr-baseCPUNanoTime;
|
||||
baseCPUNanoTime=curr;
|
||||
baseSystemNanoTime=baseSystemNanoTime.add( Long128.valueOf(nanoela).multiply(this.frequency).divide(NANOS_PER_SECONDS));
|
||||
this.frequency = frequency;
|
||||
this.frequency2=frequency*0xffffffffL/1000000000L;
|
||||
}finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@@ -59,6 +63,7 @@ public class HighAccuracyClock {
|
||||
try {
|
||||
compact();
|
||||
this.frequency = frequency+fdelta;
|
||||
this.frequency2=frequency*0xffffffffL/1000000000L;
|
||||
}finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@@ -69,7 +74,8 @@ public class HighAccuracyClock {
|
||||
lock.lock();
|
||||
try {
|
||||
long curr=System.nanoTime();
|
||||
long nanoela=curr-baseCPUNanoTime.getAndSet(curr);
|
||||
long nanoela=curr-baseCPUNanoTime;
|
||||
baseCPUNanoTime=curr;
|
||||
baseSystemNanoTime=baseSystemNanoTime.add(Long128.valueOf(nanoela).multiply(this.frequency).divide(NANOS_PER_SECONDS));
|
||||
}finally {
|
||||
lock.unlock();
|
||||
@@ -80,12 +86,8 @@ public class HighAccuracyClock {
|
||||
* 获取从1970-01-01开始的当前时间(纳秒精度)
|
||||
*/
|
||||
public Long128 getCurrentTimeNanos() {
|
||||
Long128 mul=Long128.valueOf(System.nanoTime()-baseCPUNanoTime.get()).multiply(frequency);
|
||||
if(mul.getHigh()!=0) {
|
||||
compact();
|
||||
mul=Long128.valueOf(System.nanoTime()-baseCPUNanoTime.get()).multiply(frequency);
|
||||
}
|
||||
return mul.divide(NANOS_PER_SECONDS).add(baseSystemNanoTime);
|
||||
Long128 mul=Long128.valueOf(System.nanoTime()-baseCPUNanoTime).multiply(frequency2);
|
||||
return mul.shiftRight(32).add(baseSystemNanoTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,14 +100,14 @@ public class HighAccuracyClock {
|
||||
/**
|
||||
* 获取 NTPv4 128 位时间戳
|
||||
*/
|
||||
public BigInteger getCurrentTimeNTP128() {
|
||||
public Long128 getCurrentTimeNTP128() {
|
||||
return NTPTimestamps.nanosToNtp128BitTimestamp(getCurrentTimeNanos());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 NTPv4 64 位时间戳
|
||||
*/
|
||||
public BigInteger getCurrentTimeNTP64() {
|
||||
public Long128 getCurrentTimeNTP64() {
|
||||
return NTPTimestamps.ntp128To64(getCurrentTimeNTP128());
|
||||
}
|
||||
|
||||
@@ -125,7 +127,7 @@ public class HighAccuracyClock {
|
||||
public void syncToTime(Long128 targetNanos) {
|
||||
lock.lock();
|
||||
try {
|
||||
baseCPUNanoTime.set( System.nanoTime());
|
||||
baseCPUNanoTime= System.nanoTime();
|
||||
baseSystemNanoTime=targetNanos;
|
||||
}finally {
|
||||
lock.unlock();
|
||||
@@ -152,7 +154,7 @@ public class HighAccuracyClock {
|
||||
}
|
||||
lock.lock();
|
||||
try {
|
||||
baseCPUNanoTime.set( System.nanoTime());
|
||||
baseCPUNanoTime=System.nanoTime();
|
||||
baseSystemNanoTime=referenceClock.getCurrentTimeNanos();
|
||||
}finally {
|
||||
lock.unlock();
|
||||
@@ -163,7 +165,7 @@ public class HighAccuracyClock {
|
||||
* 基于NTP时间戳同步
|
||||
* @param ntp128Timestamp NTP 128位时间戳
|
||||
*/
|
||||
public void syncToNTPTime(BigInteger ntp128Timestamp) {
|
||||
public void syncToNTPTime(Long128 ntp128Timestamp) {
|
||||
Long128 targetNanos = NTPTimestamps.ntp128BitToNanosTimestamp(ntp128Timestamp);
|
||||
syncToTime(targetNanos);
|
||||
}
|
||||
@@ -226,6 +228,11 @@ public class HighAccuracyClock {
|
||||
Long128 nanos = getCurrentTimeNanos();
|
||||
return NTPTimestamps.nanosSince1970ToString(nanos);
|
||||
}
|
||||
|
||||
public String toString2() {
|
||||
Long128 nanos = getCurrentTimeNanos();
|
||||
return NTPTimestamps.nanosSince1970ToString2(nanos);
|
||||
}
|
||||
|
||||
public long getInitialCPUNanoTime() {
|
||||
return initialCPUNanoTime;
|
||||
@@ -244,6 +251,8 @@ public class HighAccuracyClock {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.kne.cloud.clock;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
@@ -12,29 +11,30 @@ import org.kne.math.Long128;
|
||||
public class NTPTimestamps {
|
||||
|
||||
// 常量定义
|
||||
public static final BigInteger NANOS_PER_SECOND = BigInteger.valueOf(1_000_000_000L);
|
||||
public static final BigInteger NANOS_PER_MILLIS = BigInteger.valueOf(1_000_000L);
|
||||
public static final Long128 NANOS_PER_SECOND = Long128.valueOf(1_000_000_000L);
|
||||
public static final Long128 NANOS_PER_MILLIS = Long128.valueOf(1_000_000L);
|
||||
|
||||
// NTP 纪元 (1900) 和 Unix 纪元 (1970) 之间的纳秒差
|
||||
public static final BigInteger NTP_EPOCH_OFFSET_NS = BigInteger.valueOf(2208988800L)
|
||||
public static final Long128 NTP_EPOCH_OFFSET_NS = Long128.valueOf(2208988800L)
|
||||
.multiply(NANOS_PER_SECOND);
|
||||
|
||||
// 2^64 值,用于单位转换
|
||||
public static final BigInteger TWO_POW_64 = BigInteger.ONE.shiftLeft(64);
|
||||
public static final Long128 TWO_POW_64 = Long128.ONE.shiftLeft(64);
|
||||
|
||||
// 2^32 值,用于 64 位时间戳处理
|
||||
public static final BigInteger TWO_POW_32 = BigInteger.ONE.shiftLeft(32);
|
||||
public static final Long128 TWO_POW_32 = Long128.ONE.shiftLeft(32);
|
||||
|
||||
// 掩码常量
|
||||
public static final BigInteger MASK_32_BIT = new BigInteger("FFFFFFFF", 16);
|
||||
public static final BigInteger MASK_64_BIT = new BigInteger("FFFFFFFFFFFFFFFF", 16);
|
||||
public static final Long128 MASK_32_BIT = new Long128(0xFFFFFFFF);
|
||||
public static final Long128 MASK_64_BIT = new Long128(0xFFFFFFFFFFFFFFFFL);
|
||||
|
||||
// ================== 核心转换方法 ==================
|
||||
// 2^32 秒,约 136.192 年,一个 NTP 纪元的长度
|
||||
public static final BigInteger SECONDS_PER_ERA = BigInteger.valueOf(0x100000000L);
|
||||
public static final Long128 SECONDS_PER_ERA = Long128.valueOf(0x100000000L);
|
||||
private static final Long128 TWO_POW_N64_PER_NANOS = Long128.valueOf("1208925819614629");
|
||||
|
||||
public static BigInteger inferNtp64To128(long remote64Bit,BigInteger local128Bit ) {
|
||||
return inferNtp64To128(toUnsignedBigInteger(remote64Bit),local128Bit);
|
||||
public static Long128 inferNtp64To128(long remote64Bit,Long128 local128Bit ) {
|
||||
return inferNtp64To128(toUnsignedLong128(remote64Bit),local128Bit);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,26 +45,26 @@ public class NTPTimestamps {
|
||||
* @param local128Bit 本地已知的 128 位 NTP 时间戳
|
||||
* @return 推断出的完整 128 位 NTP 时间戳
|
||||
*/
|
||||
public static BigInteger inferNtp64To128(BigInteger remote64Bit,BigInteger local128Bit ) {
|
||||
public static Long128 inferNtp64To128(Long128 remote64Bit,Long128 local128Bit ) {
|
||||
// 1. 从本地 128 位时间戳中提取纪元号和 64 位时间戳部分
|
||||
BigInteger localEra = NTPTimestamps.getEraNumber(local128Bit);
|
||||
BigInteger local64Bit = NTPTimestamps.getNtp64Timestamp(local128Bit);
|
||||
Long128 localEra = NTPTimestamps.getEraNumber(local128Bit);
|
||||
Long128 local64Bit = NTPTimestamps.getNtp64Timestamp(local128Bit);
|
||||
|
||||
// 3. 计算本地和远程 64 位时间戳的差异
|
||||
BigInteger difference = remote64Bit.subtract(local64Bit);
|
||||
Long128 difference = remote64Bit.subtract(local64Bit);
|
||||
|
||||
// 4. 判断纪元关系并推断远程时间戳的纪元
|
||||
BigInteger remoteEra;
|
||||
Long128 remoteEra;
|
||||
|
||||
// 如果差异很大(超过半个纪元),可能需要调整纪元
|
||||
BigInteger halfEra = BigInteger.valueOf(Long.MAX_VALUE);
|
||||
Long128 halfEra = Long128.valueOf(Long.MAX_VALUE);
|
||||
|
||||
if (difference.compareTo(halfEra) > 0) {
|
||||
// 远程时间戳比本地小很多,可能属于上一个纪元
|
||||
remoteEra = localEra.subtract(BigInteger.ONE);
|
||||
remoteEra = localEra.subtract(Long128.ONE);
|
||||
} else if (difference.compareTo(halfEra.negate()) < 0) {
|
||||
// 远程时间戳比本地大很多,可能属于下一个纪元
|
||||
remoteEra = localEra.add(BigInteger.ONE);
|
||||
remoteEra = localEra.add(Long128.ONE);
|
||||
} else {
|
||||
// 差异不大,属于同一个纪元
|
||||
remoteEra = localEra;
|
||||
@@ -77,35 +77,36 @@ public class NTPTimestamps {
|
||||
* 将从1970年开始的纳秒数转换为 NTPv4 128 位时间戳
|
||||
* 128位时间戳表示从1900年1月1日起经过的 2⁻⁶⁴ 秒的数量
|
||||
*/
|
||||
public static BigInteger nanosToNtp128BitTimestamp(Long128 nanosSince1970) {
|
||||
public static Long128 nanosToNtp128BitTimestamp(Long128 nanosSince1970) {
|
||||
// 1. 计算从 1900 年开始的总纳秒数
|
||||
BigInteger totalNanosFrom1900 = nanosSince1970.toBigInteger().add(NTP_EPOCH_OFFSET_NS);
|
||||
Long128 totalNanosFrom1900 = nanosSince1970.add(NTP_EPOCH_OFFSET_NS);
|
||||
|
||||
// 2. 将纳秒转换为 2⁻⁶⁴ 秒单位
|
||||
return totalNanosFrom1900.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
|
||||
// return totalNanosFrom1900.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
|
||||
return totalNanosFrom1900.multiply(TWO_POW_N64_PER_NANOS).shiftRight(16);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 NTPv4 128 位时间戳转换回从1970年开始的纳秒数
|
||||
*/
|
||||
public static Long128 ntp128BitToNanosTimestamp(BigInteger ntp128Timestamp) {
|
||||
public static Long128 ntp128BitToNanosTimestamp(Long128 ntp128Timestamp) {
|
||||
// 1. 将 2⁻⁶⁴ 秒单位转换回纳秒
|
||||
BigInteger totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
|
||||
Long128 totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
|
||||
|
||||
// 2. 计算从 1970 年开始的总纳秒数
|
||||
return Long128.valueOf( totalNanosFrom1900.subtract(NTP_EPOCH_OFFSET_NS));
|
||||
return totalNanosFrom1900.subtract(NTP_EPOCH_OFFSET_NS);
|
||||
}
|
||||
|
||||
|
||||
public static BigInteger nanosToNtp128BitTimeInterval(BigInteger nanos) {
|
||||
public static Long128 nanosToNtp128BitTimeInterval(Long128 nanos) {
|
||||
// 2. 将纳秒转换为 2⁻⁶⁴ 秒单位
|
||||
return nanos.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
|
||||
}
|
||||
|
||||
|
||||
public static BigInteger ntp128BitToNanosInterval(BigInteger ntp128Timestamp) {
|
||||
public static Long128 ntp128BitToNanosInterval(Long128 ntp128Timestamp) {
|
||||
// 1. 将 2⁻⁶⁴ 秒单位转换回纳秒
|
||||
BigInteger totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
|
||||
Long128 totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
|
||||
|
||||
return totalNanosFrom1900;
|
||||
}
|
||||
@@ -117,7 +118,7 @@ public class NTPTimestamps {
|
||||
* 将 NTP 128 位时间戳转换为 NTP 64 位时间戳
|
||||
* 64位时间戳就是128位时间戳的中间64位
|
||||
*/
|
||||
public static BigInteger ntp128To64(BigInteger ntp128Timestamp) {
|
||||
public static Long128 ntp128To64(Long128 ntp128Timestamp) {
|
||||
return ntp128Timestamp.shiftRight(32).and(MASK_64_BIT);
|
||||
}
|
||||
|
||||
@@ -125,14 +126,14 @@ public class NTPTimestamps {
|
||||
* 将 NTP 64 位时间戳转换为 NTP 128 位时间戳
|
||||
* 64位时间戳放在128位时间戳的中间64位,高32位Era和低32位分数为0
|
||||
*/
|
||||
public static BigInteger ntp64To128(BigInteger ntp64Timestamp) {
|
||||
public static Long128 ntp64To128(Long128 ntp64Timestamp) {
|
||||
return ntp64Timestamp.and(MASK_64_BIT).shiftLeft(32);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 NTP 64 位时间戳转换为 NTP 128 位时间戳(指定Era Number)
|
||||
*/
|
||||
public static BigInteger ntp64To128(BigInteger ntp64Timestamp, BigInteger eraNumber) {
|
||||
public static Long128 ntp64To128(Long128 ntp64Timestamp, Long128 eraNumber) {
|
||||
return eraNumber.and(MASK_32_BIT).shiftLeft(96)
|
||||
.or(ntp64Timestamp.and(MASK_64_BIT).shiftLeft(32));
|
||||
}
|
||||
@@ -140,48 +141,48 @@ public class NTPTimestamps {
|
||||
/**
|
||||
* 从 NTP 128 位时间戳中提取 Era Number(高32位)
|
||||
*/
|
||||
public static BigInteger getEraNumber(BigInteger ntp128Timestamp) {
|
||||
public static Long128 getEraNumber(Long128 ntp128Timestamp) {
|
||||
return ntp128Timestamp.shiftRight(96).and(MASK_32_BIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 NTP 128 位时间戳中提取 64 位时间戳(中间64位)
|
||||
*/
|
||||
public static BigInteger getNtp64Timestamp(BigInteger ntp128Timestamp) {
|
||||
public static Long128 getNtp64Timestamp(Long128 ntp128Timestamp) {
|
||||
return ntp128Timestamp.shiftRight(32).and(MASK_64_BIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 NTP 128 位时间戳中提取分数部分(低32位)
|
||||
*/
|
||||
public static BigInteger getFraction(BigInteger ntp128Timestamp) {
|
||||
public static Long128 getFraction(Long128 ntp128Timestamp) {
|
||||
return ntp128Timestamp.and(MASK_32_BIT);
|
||||
}
|
||||
|
||||
// ================== 工具方法 ==================
|
||||
|
||||
/**
|
||||
* 从毫秒和纳秒偏移构造 BigInteger 纳秒
|
||||
* 从毫秒和纳秒偏移构造 Long128 纳秒
|
||||
*/
|
||||
public static Long128 toNanosSince1970(long unixTimeMillis, long nanosOffset) {
|
||||
return Long128.valueOf(unixTimeMillis)
|
||||
.multiply(Long128.valueOf( NANOS_PER_MILLIS))
|
||||
.multiply( NANOS_PER_MILLIS)
|
||||
.add(Long128.valueOf(nanosOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 BigInteger 纳秒提取毫秒和纳秒偏移
|
||||
* 从 Long128 纳秒提取毫秒和纳秒偏移
|
||||
*/
|
||||
public static long[] toMillisAndNanos(Long128 nanosSince1970) {
|
||||
Long128[] millisAndNanos = nanosSince1970.divideAndRemainder(Long128.valueOf( NANOS_PER_MILLIS));
|
||||
Long128[] millisAndNanos = nanosSince1970.divideAndRemainder( NANOS_PER_MILLIS);
|
||||
return new long[]{millisAndNanos[0].longValue(), millisAndNanos[1].longValue()};
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个 128 位时间戳之间的时间差(纳秒)
|
||||
*/
|
||||
public static BigInteger calculateTimeDifference(BigInteger timestamp1, BigInteger timestamp2) {
|
||||
BigInteger diff = timestamp2.subtract(timestamp1);
|
||||
public static Long128 calculateTimeDifference(Long128 timestamp1, Long128 timestamp2) {
|
||||
Long128 diff = timestamp2.subtract(timestamp1);
|
||||
return diff.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
|
||||
}
|
||||
|
||||
@@ -190,137 +191,20 @@ public class NTPTimestamps {
|
||||
/**
|
||||
* 将 64 位 NTP 时间戳分解为秒数和分数
|
||||
*/
|
||||
public static BigInteger[] parseNtp64Timestamp(BigInteger ntp64Timestamp) {
|
||||
BigInteger seconds = ntp64Timestamp.shiftRight(32).and(MASK_32_BIT);
|
||||
BigInteger fraction = ntp64Timestamp.and(MASK_32_BIT);
|
||||
return new BigInteger[]{seconds, fraction};
|
||||
public static Long128[] parseNtp64Timestamp(Long128 ntp64Timestamp) {
|
||||
Long128 seconds = ntp64Timestamp.shiftRight(32).and(MASK_32_BIT);
|
||||
Long128 fraction = ntp64Timestamp.and(MASK_32_BIT);
|
||||
return new Long128[]{seconds, fraction};
|
||||
}
|
||||
|
||||
/**
|
||||
* 从秒数和分数构建 64 位 NTP 时间戳
|
||||
*/
|
||||
public static BigInteger buildNtp64Timestamp(BigInteger seconds, BigInteger fraction) {
|
||||
public static Long128 buildNtp64Timestamp(Long128 seconds, Long128 fraction) {
|
||||
return seconds.and(MASK_32_BIT).shiftLeft(32).or(fraction.and(MASK_32_BIT));
|
||||
}
|
||||
|
||||
// ================== 测试代码 ==================
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== NTPv4 128位/64位时间戳转换测试 ===");
|
||||
|
||||
// 测试当前时间
|
||||
testCurrentTime();
|
||||
|
||||
// 测试 128位 ↔ 64位 转换
|
||||
test128To64Conversion();
|
||||
|
||||
// 测试 Era Number 处理
|
||||
testEraNumberHandling();
|
||||
|
||||
// 测试边界值
|
||||
testBoundaryValues();
|
||||
}
|
||||
|
||||
private static void testCurrentTime() {
|
||||
System.out.println("\n=== 当前时间测试 ===");
|
||||
|
||||
Long128 nanosSince1970 = toNanosSince1970(System.currentTimeMillis(), 123456);
|
||||
BigInteger ntp128 = nanosToNtp128BitTimestamp(nanosSince1970);
|
||||
BigInteger ntp64 = ntp128To64(ntp128);
|
||||
|
||||
System.out.println("从1970年开始的纳秒数: " + nanosSince1970);
|
||||
System.out.println("NTP 128-bit: 0x" + ntp128.toString(16).toUpperCase());
|
||||
System.out.println("NTP 64-bit: 0x" + ntp64.toString(16).toUpperCase());
|
||||
|
||||
// 反向转换验证
|
||||
BigInteger recovered128 = ntp64To128(ntp64);
|
||||
Long128 recoveredNanos = ntp128BitToNanosTimestamp(recovered128);
|
||||
|
||||
System.out.println("恢复的纳秒数: " + recoveredNanos);
|
||||
System.out.println("转换正确: " + (nanosSince1970.equals(recoveredNanos) ? "✅" : "❌"));
|
||||
}
|
||||
|
||||
private static void test128To64Conversion() {
|
||||
System.out.println("\n=== 128位 ↔ 64位 转换测试 ===");
|
||||
|
||||
// 创建一个测试用的 128 位时间戳
|
||||
BigInteger test128 = new BigInteger("EC652B7E912F00B81234567890ABCDEF", 16);
|
||||
|
||||
BigInteger ntp64 = ntp128To64(test128);
|
||||
BigInteger recovered128 = ntp64To128(ntp64);
|
||||
|
||||
System.out.println("原始128位: 0x" + test128.toString(16).toUpperCase());
|
||||
System.out.println("转换64位: 0x" + ntp64.toString(16).toUpperCase());
|
||||
System.out.println("恢复128位: 0x" + recovered128.toString(16).toUpperCase());
|
||||
|
||||
// 验证中间64位相同
|
||||
BigInteger original64Part = getNtp64Timestamp(test128);
|
||||
System.out.println("转换正确: " + (original64Part.equals(ntp64) ? "✅" : "❌"));
|
||||
}
|
||||
|
||||
private static void testEraNumberHandling() {
|
||||
System.out.println("\n=== Era Number 处理测试 ===");
|
||||
|
||||
BigInteger ntp64 = new BigInteger("EC652B7E912F00B8", 16);
|
||||
BigInteger eraNumber = new BigInteger("1", 16); // Era 1
|
||||
|
||||
BigInteger ntp128WithEra = ntp64To128(ntp64, eraNumber);
|
||||
BigInteger extractedEra = getEraNumber(ntp128WithEra);
|
||||
BigInteger extracted64 = getNtp64Timestamp(ntp128WithEra);
|
||||
|
||||
System.out.println("设置 Era: 0x" + eraNumber.toString(16).toUpperCase());
|
||||
System.out.println("提取 Era: 0x" + extractedEra.toString(16).toUpperCase());
|
||||
System.out.println("提取 64位: 0x" + extracted64.toString(16).toUpperCase());
|
||||
System.out.println("128位值: 0x" + ntp128WithEra.toString(16).toUpperCase());
|
||||
System.out.println("Era 正确: " + (eraNumber.equals(extractedEra) ? "✅" : "❌"));
|
||||
System.out.println("64位正确: " + (ntp64.equals(extracted64) ? "✅" : "❌"));
|
||||
}
|
||||
|
||||
private static void testBoundaryValues() {
|
||||
System.out.println("\n=== 边界值测试 ===");
|
||||
|
||||
// 测试最大值
|
||||
BigInteger max64 = MASK_64_BIT; // 0xFFFFFFFFFFFFFFFF
|
||||
BigInteger max128 = ntp64To128(max64);
|
||||
BigInteger recovered64 = ntp128To64(max128);
|
||||
|
||||
System.out.println("最大64位: 0x" + max64.toString(16).toUpperCase());
|
||||
System.out.println("转换128位: 0x" + max128.toString(16).toUpperCase());
|
||||
System.out.println("恢复64位: 0x" + recovered64.toString(16).toUpperCase());
|
||||
System.out.println("最大值转换正确: " + (max64.equals(recovered64) ? "✅" : "❌"));
|
||||
|
||||
// 测试 Era Number 边界
|
||||
BigInteger maxEra = MASK_32_BIT; // 0xFFFFFFFF
|
||||
BigInteger test64 = new BigInteger("1234567890ABCDEF", 16);
|
||||
BigInteger ntp128MaxEra = ntp64To128(test64, maxEra);
|
||||
BigInteger extractedMaxEra = getEraNumber(ntp128MaxEra);
|
||||
|
||||
System.out.println("最大Era转换正确: " + (maxEra.equals(extractedMaxEra) ? "✅" : "❌"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成时间序列测试
|
||||
*/
|
||||
public static void testTimeSeries() {
|
||||
System.out.println("\n=== 时间序列测试 ===");
|
||||
|
||||
Long128 startNanos = toNanosSince1970(System.currentTimeMillis(), 0);
|
||||
BigInteger start128 = nanosToNtp128BitTimestamp(startNanos);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Long128 offsetNanos = Long128.valueOf(i).multiply(Long128.valueOf( NANOS_PER_SECOND).divide(Long128.valueOf(10)));
|
||||
Long128 currentNanos = startNanos.add(offsetNanos);
|
||||
BigInteger current128 = nanosToNtp128BitTimestamp(currentNanos);
|
||||
BigInteger current64 = ntp128To64(current128);
|
||||
|
||||
long[] time = toMillisAndNanos(currentNanos);
|
||||
System.out.printf("时间: %d ms + %d ns -> 64位: %s -> 128位: %s%n",
|
||||
time[0], time[1],
|
||||
current64.toString(16).toUpperCase(),
|
||||
current128.toString(16).toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 日期时间格式化器
|
||||
private static final DateTimeFormatter DEFAULT_FORMATTER =
|
||||
@@ -338,11 +222,19 @@ public class NTPTimestamps {
|
||||
DEFAULT_FORMATTER.format(dateTime),
|
||||
nanosPart.longValue());
|
||||
}
|
||||
public static String nanosSince1970ToString2(Long128 nanos) {
|
||||
Long128 millis = nanos.divide(Long128.valueOf(1_000_000));
|
||||
|
||||
Instant instant = Instant.ofEpochMilli(millis.longValue());
|
||||
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
|
||||
return DEFAULT_FORMATTER.format(dateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 128 位时间戳转换为可读字符串
|
||||
*/
|
||||
public static String ntp128ToString(BigInteger ntp128Timestamp) {
|
||||
public static String ntp128ToString(Long128 ntp128Timestamp) {
|
||||
Long128 nanosSince1970 = ntp128BitToNanosTimestamp(ntp128Timestamp);
|
||||
return nanosSince1970ToString(nanosSince1970);
|
||||
}
|
||||
@@ -350,17 +242,17 @@ public class NTPTimestamps {
|
||||
/**
|
||||
* 将 64 位时间戳转换为可读字符串
|
||||
*/
|
||||
public static String ntp64ToString(BigInteger ntp64Timestamp) {
|
||||
public static String ntp64ToString(Long128 ntp64Timestamp) {
|
||||
Long128 nanosSince1970 = ntp128BitToNanosTimestamp(ntp64To128( ntp64Timestamp));
|
||||
return nanosSince1970ToString(nanosSince1970);
|
||||
}
|
||||
|
||||
public static BigInteger toUnsignedBigInteger(long unsignedLong) {
|
||||
public static Long128 toUnsignedLong128(long unsignedLong) {
|
||||
if (unsignedLong >= 0) {
|
||||
return BigInteger.valueOf(unsignedLong);
|
||||
return Long128.valueOf(unsignedLong);
|
||||
} else {
|
||||
// 对于负数,通过添加 2^64 来转换为无符号表示
|
||||
return BigInteger.valueOf(unsignedLong & 0x7FFFFFFFFFFFFFFFL)
|
||||
return Long128.valueOf(unsignedLong & 0x7FFFFFFFFFFFFFFFL)
|
||||
.setBit(63);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.kne.cloud.clock;
|
||||
|
||||
public class WatchDogTimer {
|
||||
private volatile long feedtime=System.nanoTime();
|
||||
private long timeout;
|
||||
public WatchDogTimer(long timeout) {
|
||||
super();
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public void feed() {
|
||||
feedtime=System.nanoTime();
|
||||
}
|
||||
|
||||
public boolean isBarking() {
|
||||
return(System.nanoTime()-feedtime)>timeout;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user