Skip to content

Commit ab1f7dc

Browse files
committed
Added functions to test which version of UUID it is.
Added ToDateTime functions to return the DateTime objects for date and time related UUIDs.
1 parent b21d0f1 commit ab1f7dc

15 files changed

Lines changed: 684 additions & 5 deletions

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## [Unreleased]
1010

11+
## [v2.3.0] - 2025-03-30
12+
[v2.3.0](https://github.com/TensionDev/UUIDUtil/releases/tag/v2.3.0)
13+
14+
### Added
15+
- Added functions to test which version of UUID it is.
16+
- Added ToDateTime functions to return the DateTime objects for date and time related UUIDs.
17+
18+
1119
## [v2.2.0] - 2025-02-22
12-
[v2.2.0](https://github.com/TensionDev/UUIDUtil/releases/tag/v2.1.0)
20+
[v2.2.0](https://github.com/TensionDev/UUIDUtil/releases/tag/v2.2.0)
1321

1422
### Changed
1523
- Changed Classes to static with private fields.

UUIDUtil/UUIDUtil.csproj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<AssemblyName>TensionDev.UUID</AssemblyName>
66
<RootNamespace>TensionDev.UUID</RootNamespace>
7+
<NuGetAuditMode>all</NuGetAuditMode>
8+
<ProduceReferenceAssembly>True</ProduceReferenceAssembly>
9+
<GenerateDocumentationFile>True</GenerateDocumentationFile>
710
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
811
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
912
<PackageId>TensionDev.UUID</PackageId>
10-
<Version>2.2.0</Version>
13+
<Version>2.3.0</Version>
1114
<Authors>TensionDev amsga</Authors>
1215
<Company>TensionDev</Company>
1316
<Product>TensionDev.UUID</Product>
@@ -19,7 +22,7 @@
1922
<RepositoryType>git</RepositoryType>
2023
<PackageTags>UUID GUID</PackageTags>
2124
<PackageReleaseNotes>Change in license to Apache License 2.0.
22-
Release with UUID / GUID Version 1, Version 3, Version 4 and Version 5, and Draft Versions 6 and 7.</PackageReleaseNotes>
25+
Release with UUID / GUID Version 1, Version 3, Version 4, Version 5, Versions 6 and 7.</PackageReleaseNotes>
2326
<NeutralLanguage>en-SG</NeutralLanguage>
2427
<IncludeSymbols>true</IncludeSymbols>
2528
<SymbolPackageFormat>snupkg</SymbolPackageFormat>

UUIDUtil/UUIDv1.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,5 +178,85 @@ public static Byte[] GetClockSequence()
178178

179179
return BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder((Int16)result));
180180
}
181+
182+
/// <summary>
183+
/// Returns true if the Uuid specified is Version 1.
184+
/// </summary>
185+
/// <param name="uuid">The Uuid to be tested.</param>
186+
/// <returns>Returns true if the Uuid specified is Version 1.</returns>
187+
public static bool IsUUIDv1(Uuid uuid)
188+
{
189+
return (uuid.ToByteArray()[6] >> 4) == 0x01;
190+
}
191+
192+
/// <summary>
193+
/// Returns the approximate DateTime used to generate the Uuid.
194+
/// </summary>
195+
/// <param name="uuid">The Uuid Version 1 object.</param>
196+
/// <returns>DateTime of the Uuid in UTC.</returns>
197+
/// <exception cref="ArgumentException"></exception>
198+
public static DateTime ToDateTime(Uuid uuid)
199+
{
200+
if (!IsUUIDv1(uuid))
201+
throw new ArgumentException(String.Format("{0} is not a Version 1 UUID.", uuid), nameof(uuid));
202+
203+
Byte[] time = new Byte[8];
204+
Byte[] hex = uuid.ToByteArray();
205+
206+
time[0] = (Byte)(hex[6] & 0x0F);
207+
time[1] = hex[7];
208+
time[2] = hex[4];
209+
time[3] = hex[5];
210+
time[4] = hex[0];
211+
time[5] = hex[1];
212+
time[6] = hex[2];
213+
time[7] = hex[3];
214+
215+
Int64 timeInterval = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt64(time, 0));
216+
TimeSpan timeSpan = TimeSpan.FromTicks(timeInterval);
217+
218+
return s_epoch.ToUniversalTime() + timeSpan;
219+
}
220+
221+
/// <summary>
222+
/// Returns the Version 6 representation of the provided Version 1 Uuid.
223+
/// </summary>
224+
/// <param name="uuid">The Uuid Version 1 object.</param>
225+
/// <returns>The converted Uuid Version 6 object.</returns>
226+
/// <exception cref="ArgumentException"></exception>
227+
public static Uuid ToUUIDv6(Uuid uuid)
228+
{
229+
if (!IsUUIDv1(uuid))
230+
throw new ArgumentException(String.Format("{0} is not a Version 1 UUID.", uuid), nameof(uuid));
231+
232+
Byte[] time = new Byte[8];
233+
Byte[] hex = uuid.ToByteArray();
234+
235+
time[0] = (Byte)(hex[6] & 0x0F);
236+
time[1] = hex[7];
237+
time[2] = hex[4];
238+
time[3] = hex[5];
239+
time[4] = hex[0];
240+
time[5] = hex[1];
241+
time[6] = hex[2];
242+
time[7] = hex[3];
243+
244+
Int64 timeInterval = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt64(time, 0));
245+
timeInterval <<= 4;
246+
time = BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder(timeInterval));
247+
248+
hex[0] = time[0];
249+
hex[1] = time[1];
250+
hex[2] = time[2];
251+
hex[3] = time[3];
252+
253+
hex[4] = time[4];
254+
hex[5] = time[5];
255+
256+
hex[6] = (Byte)(((time[6] >> 4) & 0x0F) + 0x60);
257+
hex[7] = (Byte)((time[6] << 4) + (time[7] >> 4));
258+
259+
return new Uuid(hex);
260+
}
181261
}
182262
}

UUIDUtil/UUIDv3.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,15 @@ public static Uuid NewUUIDv3(Uuid nameSpace, String name)
7171

7272
return Id;
7373
}
74+
75+
/// <summary>
76+
/// Returns true if the Uuid specified is Version 3.
77+
/// </summary>
78+
/// <param name="uuid">The Uuid to be tested.</param>
79+
/// <returns>Returns true if the Uuid specified is Version 3.</returns>
80+
public static bool IsUUIDv3(Uuid uuid)
81+
{
82+
return (uuid.ToByteArray()[6] >> 4) == 0x03;
83+
}
7484
}
7585
}

UUIDUtil/UUIDv4.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,15 @@ public static Uuid NewUUIDv4()
6767

6868
return Id;
6969
}
70+
71+
/// <summary>
72+
/// Returns true if the Uuid specified is Version 4.
73+
/// </summary>
74+
/// <param name="uuid">The Uuid to be tested.</param>
75+
/// <returns>Returns true if the Uuid specified is Version 4.</returns>
76+
public static bool IsUUIDv4(Uuid uuid)
77+
{
78+
return (uuid.ToByteArray()[6] >> 4) == 0x04;
79+
}
7080
}
7181
}

UUIDUtil/UUIDv5.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,15 @@ public static Uuid NewUUIDv5(Uuid nameSpace, String name)
7171

7272
return Id;
7373
}
74+
75+
/// <summary>
76+
/// Returns true if the Uuid specified is Version 5.
77+
/// </summary>
78+
/// <param name="uuid">The Uuid to be tested.</param>
79+
/// <returns>Returns true if the Uuid specified is Version 5.</returns>
80+
public static bool IsUUIDv5(Uuid uuid)
81+
{
82+
return (uuid.ToByteArray()[6] >> 4) == 0x05;
83+
}
7484
}
7585
}

UUIDUtil/UUIDv6.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,5 +162,86 @@ public static Byte[] GetClockSequence()
162162

163163
return BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder((Int16)result));
164164
}
165+
166+
/// <summary>
167+
/// Returns true if the Uuid specified is Version 6.
168+
/// </summary>
169+
/// <param name="uuid">The Uuid to be tested.</param>
170+
/// <returns>Returns true if the Uuid specified is Version 6.</returns>
171+
public static bool IsUUIDv6(Uuid uuid)
172+
{
173+
return (uuid.ToByteArray()[6] >> 4) == 0x06;
174+
}
175+
176+
/// <summary>
177+
/// Returns the approximate DateTime used to generate the Uuid.
178+
/// </summary>
179+
/// <param name="uuid">The Uuid Version 6 object</param>
180+
/// <returns>DateTime of the Uuid in UTC.</returns>
181+
/// <exception cref="ArgumentException"></exception>
182+
public static DateTime ToDateTime(Uuid uuid)
183+
{
184+
if (!IsUUIDv6(uuid))
185+
throw new ArgumentException(String.Format("{0} is not a Version 6 UUID.", uuid), nameof(uuid));
186+
187+
Byte[] time = new Byte[8];
188+
Byte[] hex = uuid.ToByteArray();
189+
190+
time[0] = hex[0];
191+
time[1] = hex[1];
192+
time[2] = hex[2];
193+
time[3] = hex[3];
194+
time[4] = hex[4];
195+
time[5] = hex[5];
196+
time[6] = (Byte)((Byte)((hex[6] & 0x0F) << 4) + (hex[7] >> 4));
197+
time[7] = (Byte)(hex[7] << 4);
198+
199+
Int64 timeInterval = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt64(time, 0));
200+
timeInterval >>= 4;
201+
TimeSpan timeSpan = TimeSpan.FromTicks(timeInterval);
202+
203+
return s_epoch.ToUniversalTime() + timeSpan;
204+
}
205+
206+
/// <summary>
207+
/// Returns the Version 1 representation of the provided Version 6 Uuid.
208+
/// </summary>
209+
/// <param name="uuid">The Uuid Version 6 object.</param>
210+
/// <returns>The converted Uuid Version 1 object.</returns>
211+
/// <exception cref="ArgumentException"></exception>
212+
public static Uuid ToUUIDv1(Uuid uuid)
213+
{
214+
if (!IsUUIDv6(uuid))
215+
throw new ArgumentException(String.Format("{0} is not a Version 6 UUID.", uuid), nameof(uuid));
216+
217+
Byte[] time = new Byte[8];
218+
Byte[] hex = uuid.ToByteArray();
219+
220+
time[0] = hex[0];
221+
time[1] = hex[1];
222+
time[2] = hex[2];
223+
time[3] = hex[3];
224+
time[4] = hex[4];
225+
time[5] = hex[5];
226+
time[6] = (Byte)((Byte)((hex[6] & 0x0F) << 4) + (hex[7] >> 4));
227+
time[7] = (Byte)(hex[7] << 4);
228+
229+
Int64 timeInterval = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt64(time, 0));
230+
timeInterval >>= 4;
231+
time = BitConverter.GetBytes(System.Net.IPAddress.HostToNetworkOrder(timeInterval));
232+
233+
hex[0] = time[4];
234+
hex[1] = time[5];
235+
hex[2] = time[6];
236+
hex[3] = time[7];
237+
238+
hex[4] = time[2];
239+
hex[5] = time[3];
240+
241+
hex[6] = (Byte)((time[0] & 0x0F) + 0x10);
242+
hex[7] = time[1];
243+
244+
return new Uuid(hex);
245+
}
165246
}
166247
}

UUIDUtil/UUIDv7.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public static class UUIDv7
2929
private static UInt16 s_counter = 0;
3030
private static readonly Object s_counterLock = new Object();
3131

32+
/// <summary>
33+
/// The method of generating the clock sequence and Node ID.
34+
/// </summary>
3235
public enum GenerationMethod
3336
{
3437
/// <summary>
@@ -49,6 +52,7 @@ public enum GenerationMethod
4952
/// <summary>
5053
/// Initialises a new GUID/UUID based on Version 7 (date-time)
5154
/// </summary>
55+
/// <param name="method">The method of generating the clock sequence and Node ID.</param>
5256
/// <returns>A new Uuid object</returns>
5357
public static Uuid NewUUIDv7(GenerationMethod method = GenerationMethod.Random)
5458
{
@@ -59,6 +63,7 @@ public static Uuid NewUUIDv7(GenerationMethod method = GenerationMethod.Random)
5963
/// Initialises a new GUID/UUID based on Version 7 (date-time), based on the given date and time.
6064
/// </summary>
6165
/// <param name="dateTime">Given Date and Time</param>
66+
/// <param name="method">The method of generating the clock sequence and Node ID.</param>
6267
/// <returns>A new Uuid object</returns>
6368
public static Uuid NewUUIDv7(DateTime dateTime, GenerationMethod method = GenerationMethod.Random)
6469
{
@@ -199,5 +204,45 @@ public static Byte[] GetRandomB()
199204
return fakeNode;
200205
}
201206
}
207+
208+
/// <summary>
209+
/// Returns true if the Uuid specified is Version 7.
210+
/// </summary>
211+
/// <param name="uuid">The Uuid to be tested.</param>
212+
/// <returns>Returns true if the Uuid specified is Version 7.</returns>
213+
public static bool IsUUIDv7(Uuid uuid)
214+
{
215+
return (uuid.ToByteArray()[6] >> 4) == 0x07;
216+
}
217+
218+
/// <summary>
219+
/// Returns the approximate DateTime used to generate the Uuid.
220+
/// </summary>
221+
/// <param name="uuid">The Uuid Version 7 object</param>
222+
/// <returns>DateTime of the Uuid in UTC.</returns>
223+
/// <exception cref="ArgumentException"></exception>
224+
public static DateTime ToDateTime(Uuid uuid)
225+
{
226+
if (!IsUUIDv7(uuid))
227+
throw new ArgumentException(String.Format("{0} is not a Version 7 UUID.", uuid), nameof(uuid));
228+
229+
Byte[] time = new Byte[8];
230+
Byte[] hex = uuid.ToByteArray();
231+
232+
time[0] = hex[0];
233+
time[1] = hex[1];
234+
time[2] = hex[2];
235+
time[3] = hex[3];
236+
time[4] = hex[4];
237+
time[5] = hex[5];
238+
time[6] = hex[6];
239+
time[7] = hex[7];
240+
241+
Int64 timeInterval = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt64(time, 0));
242+
timeInterval >>= 16;
243+
TimeSpan timeSpan = TimeSpan.FromMilliseconds(timeInterval);
244+
245+
return s_epoch.ToUniversalTime() + timeSpan;
246+
}
202247
}
203248
}

0 commit comments

Comments
 (0)