Skip to content

java版本,从id解析时间戳部分,跟实际实际对不上 #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
progsq opened this issue May 22, 2025 · 2 comments
Open

java版本,从id解析时间戳部分,跟实际实际对不上 #129

progsq opened this issue May 22, 2025 · 2 comments

Comments

@progsq
Copy link

progsq commented May 22, 2025

你好,请问一下为什么java版本,从id解析时间戳部分,跟实际实际对不上

@progsq
Copy link
Author

progsq commented May 22, 2025

``
@test
public void testIdGen() throws ExecutionException, InterruptedException {
// 129053495681099 (运行1年,长度:15)
// 387750301904971 (运行3年,长度:15)
// 646093214093387 (运行5年,长度:15)
// 1292658282840139 (运行10年,长度:16)
// 9007199254740992 (运行70年,达到 js Number 最大值,长度:16)
// 165399880288699493 (运行1000年,等同普通雪花算法运行1年,长度:18)
// 能用多久的解释,是指生成的ID数字,何时能增长到超过 long(有符号64位,8字节)最大值。
// 🔵 在默认配置下,ID可用 71000 年不重复。
// 🔵 在支持 1024 个工作节点时,ID可用 4480 年不重复。
// 🔵 在支持 4096 个工作节点时,ID可用 1120 年不重复。
// 全局初始化 https://github.com/yitter/IdGenerator
// 创建 IdGeneratorOptions 对象,可在构造函数中输入 WorkerId:
IdGeneratorOptions options = new IdGeneratorOptions((short) 1);
// 默认值6,限定 WorkerId 最大值为2^6-1,即默认最多支持64个节点。
options.WorkerIdBitLength = 6;
// 默认值6,限制每毫秒生成的ID个数。若生成速度超过5万个/秒,建议加大 SeqBitLength 到 10。
options.SeqBitLength = 6;
// 10 => 10线程x100万 =》8秒
// 6 => 10线程x100万 =》170秒
// 保存参数(务必调用,否则参数设置不生效):
YitIdHelper.setIdGenerator(options);
// Set set = Collections.synchronizedSet(new HashSet<>());
// List<CompletableFuture> list = new ArrayList<>();
// int step = 100000;
// long currentTimeMillis = System.currentTimeMillis();
// for (int i = 0; i < 10; i++) {
// CompletableFuture future =
// CompletableFuture.runAsync(
// () -> {
// int count = 0;
// for (int j = 0; j < 10 * step; j++) {
// long id = YitIdHelper.nextId();
// if (set.contains(id)) {
// log.info("重复了, id: {}", id);
// throw new RuntimeException("重复了");
// }
// set.add(id);
// count++;
// if (count > step) {
// count = 0;
// log.info("完成, {}, {}", step, id);
// }
// }
// });
// list.add(future);
// }
// CompletableFuture.allOf(list.toArray(new CompletableFuture[0])).get();
// log.info("总耗时: {}", (System.currentTimeMillis() - currentTimeMillis) / 1000);

long id = YitIdHelper.nextId();
// 678960221577285
log.info("id: {}", id);
// 10011010011000010101010001100011000111000001000101
String binaryString = Long.toBinaryString(id);
log.info("二进制: {}", binaryString);
// 基础时间戳(2020-01-01 00:00:00)
log.info("WorkerId: {}", extractBitsFromLong(id, 12, 7));
long extractTime = extractBitsFromLong(id, binaryString.length(), 13);
log.info("提取时间差: {}", extractTime);
log.info("相加时间差: {}", extractTime + BASE_TIME);
log.info("当前时间: {}", DateUtil.formatDateTime(new Date(extractTime + BASE_TIME)));

}

// 基础时间戳(2020-01-01 00:00:00)1577808000000
private static final long BASE_TIME = 1577808000000L;

/**

  • 从long类型数据中提取指定范围的位
  • @param number 原始数字
  • @param startBit 起始位(从1开始计数,倒数第1位为1)
  • @param endBit 结束位(从1开始计数,倒数第1位为1)
  • @return 提取的位
    */
    public static long extractBitsFromLong(long number, int startBit, int endBit) {
    // 计算掩码
    long mask = ((1L << (startBit - endBit + 1)) - 1) << (endBit - 1);
    // 提取指定范围的位
    return (number & mask) >> (endBit - 1);
    }

``

@progsq
Copy link
Author

progsq commented May 22, 2025

/** 格式化日期 */
public static String formatDate(Date date, String pattern) {
if (date == null) {
return "";
}
if (StringUtils.isEmpty(pattern)) {
pattern = "yyyy-MM-dd";
}
SimpleDateFormat formater = new SimpleDateFormat(pattern);
return formater.format(date);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant