This commit is contained in:
FH 2022-07-04 18:27:05 +02:00
parent 071dcb33f2
commit 1e96fac55a
5 changed files with 185 additions and 5 deletions

View file

@ -53,12 +53,14 @@
<ItemGroup>
<Compile Include="ExtensionsEx.cs" />
<Compile Include="Generators.cs" />
<Compile Include="GuidGenerator.cs" />
<Compile Include="GuidVersion.cs" />
<Compile Include="IRepository.cs" />
<Compile Include="IAsyncReadonlyRepo.cs" />
<Compile Include="IRepositoryEx.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VatFormatValidator.cs" />
<Compile Include="Mogrifiers.cs" />
<Compile Include="Mogrify.cs" />
<Compile Include="QueryHelper.cs" />
<Compile Include="StringOptions.cs" />
<Compile Include="Squid.cs" />

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectView>ProjectFiles</ProjectView>
<ProjectView>ShowAllFiles</ProjectView>
</PropertyGroup>
</Project>

157
GuidGenerator.cs Normal file
View file

@ -0,0 +1,157 @@
using System;
using System.Text;
namespace FCS.Lib.Utility
{
/// <summary>
/// Used for generating UUID based on RFC 4122.
/// </summary>
/// <seealso href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122 - A Universally Unique IDentifier (UUID) URN Namespace</seealso>
public static class GuidGenerator
{
// number of bytes in guid
public const int ByteArraySize = 16;
// multiplex variant info
public const int VariantByte = 8;
public const int VariantByteMask = 0x3f;
public const int VariantByteShift = 0x80;
// multiplex version info
public const int VersionByte = 7;
public const int VersionByteMask = 0x0f;
public const int VersionByteShift = 4;
// indexes within the uuid array for certain boundaries
private const byte TimestampByte = 0;
private const byte GuidClockSequenceByte = 8;
private const byte NodeByte = 10;
// offset to move from 1/1/0001, which is 0-time for .NET, to gregorian 0-time of 10/15/1582
private static readonly DateTimeOffset GregorianCalendarStart = new(1582, 10, 15, 0, 0, 0, TimeSpan.Zero);
// random clock sequence and node
public static byte[] DefaultClockSequence { get; set; }
public static byte[] DefaultNode { get; set; }
static GuidGenerator()
{
DefaultClockSequence = new byte[2];
DefaultNode = new byte[6];
var random = new Random();
random.NextBytes(DefaultClockSequence);
random.NextBytes(DefaultNode);
}
public static void SetDefaultNode(string nodeName)
{
var x = nodeName.GetHashCode();
var node = $"{x:X}";
DefaultNode = Encoding.UTF8.GetBytes(node.ToCharArray(), 0, 6);
}
public static GuidVersion GetVersion(this Guid guid)
{
var bytes = guid.ToByteArray();
return (GuidVersion)((bytes[VersionByte] & 0xFF) >> VersionByteShift);
}
public static DateTimeOffset GetDateTimeOffset(Guid guid)
{
var bytes = guid.ToByteArray();
// reverse the version
bytes[VersionByte] &= VersionByteMask;
bytes[VersionByte] |= (byte)GuidVersion.TimeBased >> VersionByteShift;
var timestampBytes = new byte[8];
Array.Copy(bytes, TimestampByte, timestampBytes, 0, 8);
var timestamp = BitConverter.ToInt64(timestampBytes, 0);
var ticks = timestamp + GregorianCalendarStart.Ticks;
return new DateTimeOffset(ticks, TimeSpan.Zero);
}
public static DateTime GetDateTime(Guid guid)
{
return GetDateTimeOffset(guid).DateTime;
}
public static DateTime GetLocalDateTime(Guid guid)
{
return GetDateTimeOffset(guid).LocalDateTime;
}
public static DateTime GetUtcDateTime(Guid guid)
{
return GetDateTimeOffset(guid).UtcDateTime;
}
public static Guid GenerateTimeBasedGuid()
{
return GenerateTimeBasedGuid(DateTimeOffset.UtcNow, DefaultClockSequence, DefaultNode);
}
public static Guid GenerateTimeBasedGuid(string nodeName)
{
var x = nodeName.GetHashCode();
var node = $"{x:X}";
var defaultNode = Encoding.UTF8.GetBytes(node.ToCharArray(), 0, 6);
return GenerateTimeBasedGuid(DateTimeOffset.UtcNow, DefaultClockSequence, defaultNode);
}
public static Guid GenerateTimeBasedGuid(DateTime dateTime)
{
return GenerateTimeBasedGuid(dateTime, DefaultClockSequence, DefaultNode);
}
public static Guid GenerateTimeBasedGuid(DateTimeOffset dateTime)
{
return GenerateTimeBasedGuid(dateTime, DefaultClockSequence, DefaultNode);
}
public static Guid GenerateTimeBasedGuid(DateTime dateTime, byte[] clockSequence, byte[] node)
{
return GenerateTimeBasedGuid(new DateTimeOffset(dateTime), clockSequence, node);
}
public static Guid GenerateTimeBasedGuid(DateTimeOffset dateTime, byte[] clockSequence, byte[] node)
{
if (clockSequence == null)
throw new ArgumentNullException(nameof(clockSequence));
if (node == null)
throw new ArgumentNullException(nameof(node));
if (clockSequence.Length != 2)
throw new ArgumentOutOfRangeException(nameof(clockSequence), "The clockSequence must be 2 bytes.");
if (node.Length != 6)
throw new ArgumentOutOfRangeException(nameof(node), "The node must be 6 bytes.");
var ticks = (dateTime - GregorianCalendarStart).Ticks;
var guid = new byte[ByteArraySize];
var timestamp = BitConverter.GetBytes(ticks);
// copy node
Array.Copy(node, 0, guid, NodeByte, Math.Min(6, node.Length));
// copy clock sequence
Array.Copy(clockSequence, 0, guid, GuidClockSequenceByte, Math.Min(2, clockSequence.Length));
// copy timestamp
Array.Copy(timestamp, 0, guid, TimestampByte, Math.Min(8, timestamp.Length));
// set the variant
guid[VariantByte] &= VariantByteMask;
guid[VariantByte] |= VariantByteShift;
// set the version
guid[VersionByte] &= VersionByteMask;
guid[VersionByte] |= (byte)GuidVersion.TimeBased << VersionByteShift;
return new Guid(guid);
}
}
}

11
GuidVersion.cs Normal file
View file

@ -0,0 +1,11 @@
namespace FCS.Lib.Utility
{
// guid version types
public enum GuidVersion
{
TimeBased = 0x01,
Reserved = 0x02,
NameBased = 0x03,
Random = 0x04
}
}

View file

@ -6,7 +6,7 @@
// Last Modified By : Frede H.
// Last Modified On : 02-24-2022
// ***********************************************************************
// <copyright file="Mogrifiers.cs" company="FCS">
// <copyright file="Mogrify.cs" company="FCS">
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the Affero GNU General Public License as
@ -35,8 +35,18 @@ using System.Text.RegularExpressions;
namespace FCS.Lib.Utility
{
public static class Mogrifiers
public static class Mogrify
{
public static int MonthFromTimestamp(long timeStamp)
{
return TimeStampToDateTime(timeStamp).Month;
}
public static bool TimestampInMonth(long timestamp, int month)
{
return TimeStampToDateTime(timestamp).Month == month;
}
public static Dictionary<string,long> DateToTimestampRange(DateTime dateTime)
{
var dt1 = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day,0,0,0);