Be very careful using com.eaio.uuid.UUID, if you need to generate GUID by time other than current time, as this will always generate the same UUID for given time. So if your data has requirement to generate UUID, where records may have same time, this will generate same UUID.
We needed this to generate UUID for records, which are created ahead and also multiple records at same time, we tried to tweak it by trying to use UUIDGen.createTime(). We found that it has a side effect to mutate the time for records out of order. If a subsequent request to create UUID has a time stamp older than previous request, you end up having a UUID, which is based on previous request's time stamp.
After all the analysis, we had to simply go back to create UUID at the time of creation, so that we don't have to pass it as an argument. Whichever solution we come up with to generate UUID at a later time, every one has a drawback.
To test our application, we have to generate data which has time-based UUID, using com.eaio.uuid.UUID we generated old time stamp UUIDs and hence were able to control the timestamp as per our test cases.
Note: - We cannot generate future timestamp UUID
We generated in below way -
import com.eaio.uuid.UUID;
import com.eaio.uuid.UUIDGen;
long time = DateUtil.getEpochtimeFromDate("21-06-2018 12:30:31", "dd-M-yyy hh:hh:ss");
UUID time_based_uuid = new UUID(UUIDGen.createTime(time), UUIDGen.getClockSeqAndNode());
Version 1 UUIDs actually represent a point in space and in time.
The "space" part is the MAC address taken from the networking port of the computer to uniquely identify where the id was generated (nearly unique, there have been some infamous screw-ups in assigning MAC addresses by the networking hardware manufacturers).
If you aren't interested in integrating Yet Another Java Library™️, here's a bit of Java code to generate Version 1 UUIDs. Home brew, so YMMV.
Pre-conditions:
clock sequence: RFC 4122 goes into a bit of details what it ideally should be, but then hand waves it with "it can be a pseudo random number", so that's what we use here.
node id: the RFC wants this to be a MAC address - I leave getting a relevant MAC address as an exercise to the reader, and in this implementation we rely on more hand waving from the RFC and use a bunch of random bytes in the correct amount, instead.
// fake clock_sequence and node_id
var rng = SecureRandom.getInstanceStrong();
short clock_sequence = (short) rng.nextInt(0x10000);
byte[] node = new byte[6];
rng.nextBytes(node);
Instant time = Instant.now(); // if you don't want "now", pick something else
var dur = Duration.between(ZonedDateTime.of(1582, 10, 15, 0, 0, 0, 0,
ZoneOffset.UTC), // RFC-specified epoch, no idea why
time.atZone(ZoneOffset.UTC));
var timestamp = dur.getSeconds() * 10000 + dur.getNano() / 100;
var time_low = timestamp & 0xFFFFFFFFL;
timestamp >>>= 32;
var time_mid = timestamp & 0xFFFFL;
timestamp >>>= 16;
var time_high_and_ver = timestamp & 0xFFF | (1 << 12); // add version 1
var msb = time_low << 32 | time_mid << 16 | time_high_and_ver;
ByteBuffer data = ByteBuffer.allocate(8);
data.putShort(clock_sequence & 0x3FFF | 0x8000); // add RFC variant
data.put(node);
data.flip();
var lsb = data.getLong();
// compose the UUID
return new java.util.UUID(msb, lsb);