]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.api.uuid/src/org/argeo/api/uuid/TimeUuid.java
Kerberos does not try to use shared state
[lgpl/argeo-commons.git] / org.argeo.api.uuid / src / org / argeo / api / uuid / TimeUuid.java
1 package org.argeo.api.uuid;
2
3 import java.time.Duration;
4 import java.time.Instant;
5 import java.time.ZoneOffset;
6 import java.time.ZonedDateTime;
7 import java.util.UUID;
8
9 /**
10 * A time based UUID, whose content can therefore be usefully interpreted as
11 * time and node identifier information.
12 */
13 public class TimeUuid extends TypedUuid {
14 private static final long serialVersionUID = APM.SERIAL;
15 /**
16 * Start of the Gregorian time on October 15th 1582, equivalent to
17 * <code>{@link UUID#timestamp()} == 0</code>.
18 */
19 public final static Instant TIMESTAMP_ZERO = ZonedDateTime.of(1582, 10, 15, 0, 0, 0, 0, ZoneOffset.UTC).toInstant();
20
21 /** Constructor based on a {@link UUID}. */
22 public TimeUuid(UUID uuid) {
23 super(uuid);
24 if (uuid.version() != 1 && uuid.variant() != 2)
25 throw new IllegalArgumentException("The provided UUID is not a time based UUID.");
26 }
27
28 /** {@link UUID#timestamp()} as an {@link Instant}. */
29 public final Instant getInstant() {
30 long timestamp = uuid.timestamp();
31 return TIMESTAMP_ZERO.plus(timestampDifferenceToDuration(timestamp));
32 }
33
34 /** {@link UUID#node()} as an hex string. */
35 public final String getNodeId() {
36 return Long.toHexString(uuid.node());
37 }
38
39 /** {@link UUID#clockSequence()} as an hex string. */
40 public final String getClockSequence() {
41 return Long.toHexString(uuid.clockSequence());
42 }
43
44 /**
45 * Always returns <code>false</code> since time UUIDs are by definition not
46 * opaque.
47 */
48 @Override
49 public final boolean isOpaque() {
50 return false;
51 }
52
53 /*
54 * STATIC UTILITIES
55 */
56 /** Converts from duration in the time UUID timestamp format. */
57 public static Duration timestampDifferenceToDuration(long timestampDifference) {
58 long seconds = timestampDifference / 10000000;
59 long nano = (timestampDifference % 10000000) * 100;
60 return Duration.ofSeconds(seconds, nano);
61 }
62
63 /**
64 * A duration expressed in the time UUID timestamp format based on units of 100
65 * ns.
66 */
67 public static long durationToTimestamp(Duration duration) {
68 return (duration.getSeconds() * 10000000 + duration.getNano() / 100);
69 }
70
71 /**
72 * An instant expressed in the time UUID timestamp format based on units of 100
73 * ns since {@link #TIMESTAMP_ZERO}.
74 */
75 public static long instantToTimestamp(Instant instant) {
76 Duration duration = Duration.between(TimeUuid.TIMESTAMP_ZERO, instant);
77 return durationToTimestamp(duration);
78 }
79
80 /**
81 * Crate a time UUID with this instant as timestamp and clock and node id set to
82 * zero.
83 */
84 public static UUID fromInstant(Instant instant) {
85 long timestamp = instantToTimestamp(instant);
86 long mostSig = toMostSignificantBits(timestamp);
87 UUID uuid = new UUID(mostSig, UuidFactory.LEAST_SIG_RFC4122_VARIANT);
88 return uuid;
89 }
90
91 /** Convert timestamp in UUID format to most significant bits of a time UUID. */
92 static long toMostSignificantBits(long timestamp) {
93 long mostSig = UuidFactory.MOST_SIG_VERSION1 | ((timestamp & 0xFFFFFFFFL) << 32) // time_low
94 | (((timestamp >> 32) & 0xFFFFL) << 16) // time_mid
95 | ((timestamp >> 48) & 0x0FFFL);// time_hi_and_version
96 return mostSig;
97 }
98 }