From 656ce5d46b91b437fc80eed85a93f87d5f89bf23 Mon Sep 17 00:00:00 2001 From: Muntadhar Haydar Date: Mon, 29 May 2023 17:00:31 +0300 Subject: [PATCH 1/2] add min and max at static methods --- NUlid/Ulid.cs | 56 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/NUlid/Ulid.cs b/NUlid/Ulid.cs index 4cc6d12..9a8721c 100644 --- a/NUlid/Ulid.cs +++ b/NUlid/Ulid.cs @@ -1,11 +1,11 @@ -using NUlid.Rng; -using System; +using System; +using System.Buffers.Binary; using System.ComponentModel; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; -using System.Buffers.Binary; +using NUlid.Rng; #if NET6_0_OR_GREATER using System.Runtime.Intrinsics; @@ -53,12 +53,12 @@ public struct Ulid : IEquatable, IComparable, IComparable, ISerializ /// /// Represents the smallest possible value of . This field is read-only. /// - public static readonly Ulid MinValue = new(EPOCH, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + public static readonly Ulid MinValue = MinAt(EPOCH); /// /// Represents the largest possible value of . This field is read-only. /// - public static readonly Ulid MaxValue = new(DateTimeOffset.MaxValue, new byte[] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }); + public static readonly Ulid MaxValue = MaxAt(DateTimeOffset.MaxValue); /// /// A read-only instance of the structure whose value is all zeros. @@ -104,6 +104,22 @@ public static Ulid NewUlid(DateTimeOffset time) public static Ulid NewUlid(IUlidRng rng) => NewUlid(DateTimeOffset.UtcNow, rng); + /// + /// Creates and returns a new that is the minimum possible value for the specified time. + /// + /// The to use for the time-part of the . + /// Returns a new . + public static Ulid MinAt(DateTimeOffset time) + => new(time, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); + + /// + /// Creates and returns a new that is the maximum possible value for the specified time. + /// + /// The to use for the time-part of the . + /// Returns a new . + public static Ulid MaxAt(DateTimeOffset time) + => new(time, new byte[] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }); + /// /// Creates and returns a new based on the specified time and using the specified RNG. /// @@ -243,7 +259,7 @@ private Ulid(DateTimeOffset timePart, ReadOnlySpan randomPart) #endif } -#region Helper functions + #region Helper functions private static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds) { var ticks = (milliseconds * TimeSpan.TicksPerMillisecond) + (UNIXEPOCHMILLISECONDS * 10000); @@ -306,23 +322,23 @@ private static void ToBase32(ReadOnlySpan value, Span buffer) // Time part if (value.Length == 6 && buffer.Length > 10) { - buffer[0] = BASE32[(value[0] & 224) >> 5]; buffer[1] = BASE32[value[0] & 31]; - buffer[2] = BASE32[(value[1] & 248) >> 3]; buffer[3] = BASE32[((value[1] & 7) << 2) | ((value[2] & 192) >> 6)]; - buffer[4] = BASE32[(value[2] & 62) >> 1]; buffer[5] = BASE32[((value[2] & 1) << 4) | ((value[3] & 240) >> 4)]; - buffer[6] = BASE32[((value[3] & 15) << 1) | ((value[4] & 128) >> 7)]; buffer[7] = BASE32[(value[4] & 124) >> 2]; - buffer[8] = BASE32[((value[4] & 3) << 3) | ((value[5] & 224) >> 5)]; buffer[9] = BASE32[value[5] & 31]; + buffer[0] = BASE32[(value[0] & 224) >> 5]; buffer[1] = BASE32[value[0] & 31]; + buffer[2] = BASE32[(value[1] & 248) >> 3]; buffer[3] = BASE32[((value[1] & 7) << 2) | ((value[2] & 192) >> 6)]; + buffer[4] = BASE32[(value[2] & 62) >> 1]; buffer[5] = BASE32[((value[2] & 1) << 4) | ((value[3] & 240) >> 4)]; + buffer[6] = BASE32[((value[3] & 15) << 1) | ((value[4] & 128) >> 7)]; buffer[7] = BASE32[(value[4] & 124) >> 2]; + buffer[8] = BASE32[((value[4] & 3) << 3) | ((value[5] & 224) >> 5)]; buffer[9] = BASE32[value[5] & 31]; } // Random part else if (value.Length == 10 && buffer.Length >= 16) { - buffer[0] = BASE32[(value[0] & 248) >> 3]; buffer[1] = BASE32[((value[0] & 7) << 2) | ((value[1] & 192) >> 6)]; - buffer[2] = BASE32[(value[1] & 62) >> 1]; buffer[3] = BASE32[((value[1] & 1) << 4) | ((value[2] & 240) >> 4)]; - buffer[4] = BASE32[((value[2] & 15) << 1) | ((value[3] & 128) >> 7)]; buffer[5] = BASE32[(value[3] & 124) >> 2]; - buffer[6] = BASE32[((value[3] & 3) << 3) | ((value[4] & 224) >> 5)]; buffer[7] = BASE32[value[4] & 31]; - buffer[8] = BASE32[(value[5] & 248) >> 3]; buffer[9] = BASE32[((value[5] & 7) << 2) | ((value[6] & 192) >> 6)]; - buffer[10] = BASE32[(value[6] & 62) >> 1]; buffer[11] = BASE32[((value[6] & 1) << 4) | ((value[7] & 240) >> 4)]; + buffer[0] = BASE32[(value[0] & 248) >> 3]; buffer[1] = BASE32[((value[0] & 7) << 2) | ((value[1] & 192) >> 6)]; + buffer[2] = BASE32[(value[1] & 62) >> 1]; buffer[3] = BASE32[((value[1] & 1) << 4) | ((value[2] & 240) >> 4)]; + buffer[4] = BASE32[((value[2] & 15) << 1) | ((value[3] & 128) >> 7)]; buffer[5] = BASE32[(value[3] & 124) >> 2]; + buffer[6] = BASE32[((value[3] & 3) << 3) | ((value[4] & 224) >> 5)]; buffer[7] = BASE32[value[4] & 31]; + buffer[8] = BASE32[(value[5] & 248) >> 3]; buffer[9] = BASE32[((value[5] & 7) << 2) | ((value[6] & 192) >> 6)]; + buffer[10] = BASE32[(value[6] & 62) >> 1]; buffer[11] = BASE32[((value[6] & 1) << 4) | ((value[7] & 240) >> 4)]; buffer[12] = BASE32[((value[7] & 15) << 1) | ((value[8] & 128) >> 7)]; buffer[13] = BASE32[(value[8] & 124) >> 2]; - buffer[14] = BASE32[((value[8] & 3) << 3) | ((value[9] & 224) >> 5)]; buffer[15] = BASE32[value[9] & 31]; + buffer[14] = BASE32[((value[8] & 3) << 3) | ((value[9] & 224) >> 5)]; buffer[15] = BASE32[value[9] & 31]; } } @@ -383,7 +399,7 @@ private static byte[] FromBase32(ReadOnlySpan v) throw new InvalidOperationException(INVALIDLENGTHMESSAGE); } #endif -#endregion + #endregion #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER /// @@ -867,4 +883,4 @@ public string ToString(string? format, IFormatProvider? formatProvider) //public static Ulid FromString(string ulid) => new Ulid(ulid); //public static implicit operator Ulid(string ulid) => FromString(ulid); //public static implicit operator string(Ulid ulid) => ulid.ToString(); -} \ No newline at end of file +} From 29524b72b9805b9c4f1f573daa8364265a1eb852 Mon Sep 17 00:00:00 2001 From: Muntadhar Haydar Date: Mon, 24 Jul 2023 14:08:13 +0300 Subject: [PATCH 2/2] methods --- .vscode/settings.json | 3 ++ NUlid/DateTimeExtensions.cs | 33 +++++++++++++++ NUlid/NUlid.csproj | 80 ++++++++++++++++++------------------- global.json | 7 ++++ 4 files changed, 82 insertions(+), 41 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 NUlid/DateTimeExtensions.cs create mode 100644 global.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3bde2e5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dotnet.defaultSolution": "NUlid.sln" +} diff --git a/NUlid/DateTimeExtensions.cs b/NUlid/DateTimeExtensions.cs new file mode 100644 index 0000000..b3474b8 --- /dev/null +++ b/NUlid/DateTimeExtensions.cs @@ -0,0 +1,33 @@ +using System; + +namespace NUlid; + +/// +/// Extension methods for and to create s. +/// +public static class DateTimeExtensions +{ + /// + /// Returns a new based on the current value. + /// + /// date time offset to base new ULID upon + /// A new + public static Ulid NewUlid(this DateTimeOffset dateTimeOffset) + => Ulid.NewUlid(dateTimeOffset); + + /// + /// Returns the minimum based on the current value. + /// + /// date time offset to base new ULID upon + /// A new + public static Ulid MinUlid(this DateTimeOffset dateTimeOffset) + => Ulid.MinAt(dateTimeOffset); + + /// + /// Returns the maximum based on the current value. + /// + /// date time offset to base new ULID upon + /// A new + public static Ulid MaxUlid(this DateTimeOffset dateTimeOffset) + => Ulid.MaxAt(dateTimeOffset); +} diff --git a/NUlid/NUlid.csproj b/NUlid/NUlid.csproj index 2394e78..9adb4ba 100644 --- a/NUlid/NUlid.csproj +++ b/NUlid/NUlid.csproj @@ -1,47 +1,45 @@  - - netstandard2.0;net6.0 - RobIII - RobIII - NUlid - true - NUlid - (C) 2016 - 2022 Devcorner.nl - enable - true - MIT - https://github.com/RobThree/NUlid - Universally Unique Lexicographically Sortable Identifier, ULID, UUID, GUID - Fixed bug in Monotonic UlidRng that could cause duplicate values when under high concurrency (see https://github.com/RobThree/NUlid/pull/17). Added MicrosecondUlidRng. - true - A .Net ULID implementation - 1.7.0 - latest - logo.png - True - bin\Release\nulid.xml - Debug;Release - true - latest - + + netstandard2.0;net6.0 + RobIII, Muntadhar Haydar + RobIII, Morabaa Software Solutions, LTD. + NUlid + true + NUlid + (C) 2016 - 2023 Devcorner.nl, Morabaa Software Solutions, LTD. + enable + MIT + https://github.com/MorabaaSoftwareSolutions/NUlid + Universally Unique Lexicographically Sortable Identifier, ULID, UUID, GUID + true + A .Net ULID implementation + 1.8.0 + preview + logo.png + True + bin\Release\nulid.xml + Debug;Release + true + latest + - - TRACE;RELEASE - + + TRACE;RELEASE + - - bin\release\NUlid.xml - + + bin\release\NUlid.xml + - - - + + + - - - True - - - - \ No newline at end of file + + + True + + + + diff --git a/global.json b/global.json new file mode 100644 index 0000000..64e45bd --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "6.0.100", + "allowPrerelease": false, + "rollForward": "latestMinor" + } +}