如何在特定日期或之前 24 小时使用 fasterxml 获取 TimeBasedUuID

how to get TimeBasedUuID using fasterxml for a specific date or for 24hrs before

您好,我正在尝试生成前一天的 timeBasedUUID。 但它总是返回当前日期的 UUID。

我的代码:

public static long getTimeFromUUID(UUID uuid) {
return (uuid.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH) / 10000;
   }

public static void timeBasedGenerator() {
    try {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -1);
        UUIDTimer timer = new UUIDTimer(new Random(cal.getTimeInMillis()), null);
        TimeBasedGenerator uuidV1Generator = Generators.timeBasedGenerator(EthernetAddress.fromInterface(), timer);
        UUID uuid = uuidV1Generator.generate();
        System.out.println("uuid.toString() = " + uuid.toString());
        //UUID uuid = UUID.fromString(uuidString);
        long time = getTimeFromUUID(uuid);
        Date date = new Date(time);
        System.out.println(date);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我正在使用 com.fasterxml.uuid 依赖项。

提前致谢

示例 1

您可以将 UUIDClock 改写为 return 24 小时前的日期。作者明确允许覆盖 class.

这是使用您的代码的示例:

package com.example;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

import com.fasterxml.uuid.EthernetAddress;
import com.fasterxml.uuid.Generators;
import com.fasterxml.uuid.UUIDClock;
import com.fasterxml.uuid.UUIDTimer;
import com.fasterxml.uuid.impl.TimeBasedGenerator;

public class MyUuidGenerator {

    public static class MyUUIDClock extends UUIDClock {

        private static final long A_DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000;

        /**
         * Returns the current time in milliseconds for 24 hours before.
         */
        @Override
        public long currentTimeMillis() {
            return System.currentTimeMillis() - A_DAY_IN_MILLISECONDS;
        }
    }
    
    private static final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 12219292800L * 10_000_000L;

    public static long getTimeFromUUID(UUID uuid) {
        return (uuid.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH) / 10000;
    }

    public static void timeBasedGenerator() {
        try {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.DAY_OF_MONTH, -1);
            MyUUIDClock clock = new MyUUIDClock(); // USING MY VERSION OF UUID CLOCK
            UUIDTimer timer = new UUIDTimer(new Random(cal.getTimeInMillis()), null, clock);
            TimeBasedGenerator uuidV1Generator = Generators.timeBasedGenerator(EthernetAddress.fromInterface(), timer);
            UUID uuid = uuidV1Generator.generate();
            System.out.println("uuid.toString() = " + uuid.toString());
            // UUID uuid = UUID.fromString(uuidString);
            long time = getTimeFromUUID(uuid);
            Date date = new Date(time);
            System.out.println(date);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static final void main(String[] args) {

        timeBasedGenerator();
    }
}

示例 2

此示例可以在使用 fasterxml 和 java-8 之前生成特定时间或 24 小时的 UUID。

package com.exemple;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.UUID;

import com.fasterxml.uuid.Generators;

public class MyUuidGenerator {

    // 1582-10-15T00:00:00.000Z
    private static final long GREG_EPOCH = -12219292800L;

    private static final long TICK = 100; // 1 tick = 100ns
    private static final long TICKS_PER_SECOND = 10_000_000L;

    public static UUID getUuidForSpecificTime(Instant instant) {
        UUID uuid = Generators.timeBasedGenerator().generate();
        return setInstant(uuid, instant);
    }

    public static UUID getUuidFor24HoursBefore() {
        UUID uuid = Generators.timeBasedGenerator().generate();
        Instant instant = getInstant(uuid).minus(24, ChronoUnit.HOURS);
        return getUuidForSpecificTime(instant);
    }

    private static Instant getInstant(UUID uuid) {
        long timestamp = uuid.timestamp();
        long secs = (timestamp / TICKS_PER_SECOND) + GREG_EPOCH;
        long nano = (timestamp % TICKS_PER_SECOND) * TICK;
        return Instant.ofEpochSecond(secs, nano);
    }

    private static UUID setInstant(UUID uuid, Instant instant) {
        final long secs = instant.getEpochSecond() - GREG_EPOCH;
        final long nano = instant.getNano();
        final long ts = (secs * TICKS_PER_SECOND) + (nano / TICK);
        final long msb = (((ts >>> 48) & 0x0FFFL) | 0x1000) | (((ts >>> 32) & 0xFFFFL) << 16) | ts << 32;
        return new UUID(msb, uuid.getLeastSignificantBits());
    }

    public static final void main(String[] args) {

        // GENERATE UUID WITH CURRENT TIME
        UUID uuid1 = Generators.timeBasedGenerator().generate();
        Instant instant1 = getInstant(uuid1);
        System.out.println(String.format("CURRENT:    uuid='%s', instant='%s'", uuid1, instant1));

        // GENERATE UUID FOR 24 HOURS BEFORE
        UUID uuid2 = getUuidFor24HoursBefore();
        Instant instant2 = getInstant(uuid2);
        System.out.println(String.format("24H BEFORE: uuid='%s', instant='%s'", uuid2, instant2));

        // GENERATE UUID FOR SPECIFIC TIME
        UUID uuid3 = getUuidForSpecificTime(Instant.parse("1999-12-31T23:59:59.999999999Z"));
        Instant instant3 = getInstant(uuid3);
        System.out.println(String.format("SPEC TIME:  uuid='%s', instant='%s'", uuid3, instant3));
    }
}

输出:

CURRENT:    uuid='f866cca9-11fc-11ec-a904-2b9a77798447', instant='2021-09-10T06:04:33.856016900Z'
24H BEFORE: uuid='ce01044a-1133-11ec-a904-0549d5549f8b', instant='2021-09-09T06:04:33.882017Z'
SPEC TIME:  uuid='63afffff-bfde-11d3-a904-8562adc72b58', instant='1999-12-31T23:59:59.999999900Z'

如果您可以向您的项目添加另一个依赖项,也许您可​​以使用 uuid-creator。这是另一个包含 2 行的示例:

Instant for24HoursBefore = Instant.now().minus(24, ChronoUnit.HOURS);
UUID uuid = UuidCreator.getTimeBased(for24HoursBefore, null, null);