Skip to content

Commit e8decf1

Browse files
authored
Merge pull request #38 from I-RzR-I/feature/AddStringDateTimeGuidExt_1
Feature/add string date time guid ext 1
2 parents cb8f62a + eca8500 commit e8decf1

9 files changed

Lines changed: 361 additions & 38 deletions

File tree

docs/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
### **v3.3.0.5249** [[RzR](mailto:108324929+I-RzR-I@users.noreply.github.com)] 29-09-2025
2+
* [325ff42] (RzR) -> Auto commit uncommited files
3+
* [7385809] (RzR) -> Add new Guid extension methods: `NullIfEmpty`, `EmptyIfNull`, `IsMissing`, `HasValidValue`.
4+
* [a37096b] (RzR) -> Add new DateTime extension methods: `IsOnlyDate`, `ForceMillisecondsToZero`.
5+
* [d0f9816] (RzR) -> Commented some tests, but it's fully covered.
6+
* [a01da4d] (RzR) -> Add new string extension `TruncateFromStart`.
7+
18
### **v3.2.0.4113** [[RzR](mailto:108324929+I-RzR-I@users.noreply.github.com)] 13-08-2025
29
* [b16c919] (RzR) -> Auto commit uncommited files
310
* [b9538c3] (RzR) -> Add missign BASE32 methods: `Base32Encode`, `Base32Decode`. Adjust existing `IsBase32String`.

src/DomainCommonExtensions/DataTypeExtensions/DateTimeExtensions.cs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,80 @@ public static double ToExcelTime(this DateTime sourceTime)
531531
/// <param name="sourceTime">Source date time</param>
532532
/// <returns>Return always epoch date.</returns>
533533
/// <remarks></remarks>
534-
public static DateTime Epoch(this DateTime sourceTime)
534+
public static DateTime Epoch(this DateTime sourceTime)
535535
=> new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
536+
537+
/// <summary>
538+
/// A DateTime extension method that query if 'sourceDateTime' is only date.
539+
/// </summary>
540+
/// <param name="sourceDateTime">The sourceDateTime to act on.</param>
541+
/// <returns>
542+
/// True if only date, false if not.
543+
/// </returns>
544+
public static bool IsOnlyDate(this DateTime sourceDateTime)
545+
=> sourceDateTime.IsNotNull()
546+
&& sourceDateTime == new DateTime(
547+
sourceDateTime.Year,
548+
sourceDateTime.Month,
549+
sourceDateTime.Day, 0, 0, 0);
550+
551+
/// <summary>
552+
/// A DateTime extension method that query if 'sourceDateTime' is only date.
553+
/// </summary>
554+
/// <param name="sourceDateTime">The sourceDateTime to act on.</param>
555+
/// <returns>
556+
/// True if only date, false if not.
557+
/// </returns>
558+
public static bool IsOnlyDate(this DateTime? sourceDateTime)
559+
=> sourceDateTime.IsNotNull()
560+
&& sourceDateTime == new DateTime(
561+
sourceDateTime!.Value!.Year,
562+
sourceDateTime!.Value!.Month,
563+
sourceDateTime!.Value!.Day, 0, 0, 0);
564+
565+
/// <summary>
566+
/// A DateTime extension method that force/set milliseconds from source date to zero.
567+
/// </summary>
568+
/// <param name="sourceDateTime">The sourceDateTime to act on.</param>
569+
/// <returns>
570+
/// A DateTime.
571+
/// </returns>
572+
public static DateTime ForceMillisecondsToZero(this DateTime sourceDateTime)
573+
=> new DateTime(sourceDateTime.Year, sourceDateTime.Month, sourceDateTime.Day,
574+
sourceDateTime.Hour, sourceDateTime.Minute, sourceDateTime.Second);
575+
576+
/// <summary>
577+
/// A DateTime extension method that force/set milliseconds from source date to zero.
578+
/// </summary>
579+
/// <param name="sourceDateTime">The sourceDateTime to act on.</param>
580+
/// <returns>
581+
/// A DateTime.
582+
/// </returns>
583+
public static DateTime? ForceMillisecondsToZero(this DateTime? sourceDateTime)
584+
{
585+
if (sourceDateTime.IsNull())
586+
return null;
587+
588+
return new DateTime(sourceDateTime!.Value!.Year, sourceDateTime!.Value!.Month, sourceDateTime!.Value!.Day,
589+
sourceDateTime!.Value!.Hour, sourceDateTime!.Value!.Minute, sourceDateTime!.Value!.Second);
590+
}
591+
592+
/// <summary>
593+
/// A DateTime extension method that force/set milliseconds from source date to zero.
594+
/// </summary>
595+
/// <param name="sourceDateTime">The sourceDateTime to act on.</param>
596+
/// <param name="defaultDateTime">
597+
/// The default DateTime value to set in case of null <para>input</para>
598+
/// </param>
599+
/// <returns>
600+
/// A DateTime.
601+
/// </returns>
602+
public static DateTime ForceMillisecondsToZero(this DateTime? sourceDateTime, DateTime defaultDateTime)
603+
{
604+
var notNullDate = sourceDateTime.AsNotNull(defaultDateTime);
605+
606+
return new DateTime(notNullDate.Year, notNullDate.Month, notNullDate.Day,
607+
notNullDate.Hour, notNullDate.Minute, notNullDate.Second);
608+
}
536609
}
537610
}

src/DomainCommonExtensions/DataTypeExtensions/GuidExtensions.cs

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,104 @@ public static long ToLong(this Guid uuid)
8686

8787
/// -------------------------------------------------------------------------------------------------
8888
/// <summary>
89-
/// A Guid? extension method that query if 'source' is empty.
89+
/// A Guid? extension method that query if 'source' Guid value is missing (empty or null).
9090
/// </summary>
9191
/// <param name="source">Source Guid value to be checked.</param>
9292
/// <returns>
9393
/// True if empty, false if not.
9494
/// </returns>
9595
/// =================================================================================================
96-
public static bool IsEmpty(this Guid? source) => source.IsNull() || source == Guid.Empty;
96+
public static bool IsMissing(this Guid? source) => source.IsNull() || source == Guid.Empty;
9797

9898
/// -------------------------------------------------------------------------------------------------
9999
/// <summary>
100-
/// A Guid? extension method that query if 'source' is empty.
100+
/// A Guid? extension method that query if 'source' Guid value is empty.
101+
/// </summary>
102+
/// <param name="source">Source Guid value to be checked.</param>
103+
/// <remarks>
104+
/// Check if source Guid value is not null and is equal with Guid.Empty.
105+
/// </remarks>
106+
/// <returns>
107+
/// True if empty, false if not.
108+
/// </returns>
109+
/// =================================================================================================
110+
public static bool IsEmpty(this Guid? source) => source.IsNotNull() && source == Guid.Empty;
111+
112+
/// -------------------------------------------------------------------------------------------------
113+
/// <summary>
114+
/// A Guid extension method that query if 'source' Guid value is empty.
101115
/// </summary>
102116
/// <param name="source">Source Guid value to be checked.</param>
103117
/// <returns>
104118
/// True if empty, false if not.
105119
/// </returns>
106120
/// =================================================================================================
107121
public static bool IsEmpty(this Guid source) => source == Guid.Empty;
122+
123+
/// -------------------------------------------------------------------------------------------------
124+
/// <summary>
125+
/// A GUID extension method that set value to null if is empty.
126+
/// </summary>
127+
/// <param name="source">Source Guid value to be checked.</param>
128+
/// <returns>
129+
/// A Guid?
130+
/// </returns>
131+
/// =================================================================================================
132+
public static Guid? NullIfEmpty(this Guid source) => source.IsEmpty() ? null : source;
133+
134+
/// -------------------------------------------------------------------------------------------------
135+
/// <summary>
136+
/// A GUID extension method that set value to null if is empty.
137+
/// </summary>
138+
/// <param name="source">Source Guid value to be checked.</param>
139+
/// <returns>
140+
/// A Guid?
141+
/// </returns>
142+
/// =================================================================================================
143+
public static Guid? NullIfEmpty(this Guid? source) => source.IsEmpty() ? null : source;
144+
145+
/// -------------------------------------------------------------------------------------------------
146+
/// <summary>
147+
/// A GUID extension method that set Guid.Empty if the source value is null.
148+
/// </summary>
149+
/// <param name="source">Source Guid value to be checked.</param>
150+
/// <returns>
151+
/// A GUID.
152+
/// </returns>
153+
/// =================================================================================================
154+
public static Guid EmptyIfNull(this Guid source) => source.IsNull() ? Guid.Empty: source;
155+
156+
/// -------------------------------------------------------------------------------------------------
157+
/// <summary>
158+
/// A GUID extension method that set Guid.Empty if the source value is null.
159+
/// </summary>
160+
/// <param name="source">Source Guid value to be checked.</param>
161+
/// <returns>
162+
/// A GUID.
163+
/// </returns>
164+
/// =================================================================================================
165+
public static Guid EmptyIfNull(this Guid? source) => source.IsNull() ? Guid.Empty : (Guid)source!;
166+
167+
/// -------------------------------------------------------------------------------------------------
168+
/// <summary>
169+
/// A GUID extension method that query if 'source' has valid value (is not null and is not equal with Guid.Empty).
170+
/// </summary>
171+
/// <param name="source">Source Guid value to be checked.</param>
172+
/// <returns>
173+
/// True if valid value, false if not.
174+
/// </returns>
175+
/// =================================================================================================
176+
public static bool HasValidValue(this Guid source) => source.IsNotNull() && source != Guid.Empty;
177+
178+
/// -------------------------------------------------------------------------------------------------
179+
/// <summary>
180+
/// A GUID extension method that query if 'source' has valid value (is not null and is not equal with Guid.Empty).
181+
/// </summary>
182+
/// <param name="source">Source Guid value to be checked.</param>
183+
/// <returns>
184+
/// True if valid value, false if not.
185+
/// </returns>
186+
/// =================================================================================================
187+
public static bool HasValidValue(this Guid? source) => source.IsNotNull() && source != Guid.Empty;
108188
}
109189
}

src/DomainCommonExtensions/DataTypeExtensions/StringExtensions.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ namespace DomainCommonExtensions.DataTypeExtensions
5252
public static class StringExtensions
5353
{
5454
private static readonly string[] DateFormats =
55-
{"yyyy-MM-dd", "MM/dd/yyyy", "M/dd/yyyy", "M/d/yyyy", "MM/d/yyyy", "yyyyMMdd"};
55+
{ "yyyy-MM-dd", "MM/dd/yyyy", "M/dd/yyyy", "M/d/yyyy", "MM/d/yyyy", "yyyyMMdd" };
5656

5757
/// <summary>
5858
/// Split string
@@ -170,6 +170,34 @@ public static string Truncate(this string text, int maxLength, bool useDots = fa
170170
return truncatedString;
171171
}
172172

173+
/// <summary>
174+
/// Truncates the string to a specified length and replace the truncated to a ...
175+
/// </summary>
176+
/// <param name="text">String that will be truncated</param>
177+
/// <param name="maxLength">Total length of characters to maintain before the truncate happens</param>
178+
/// <param name="useDots">Use 3 dots(...) in the start of string</param>
179+
/// <returns>Truncated string</returns>
180+
public static string TruncateFromStart(this string text, int maxLength, bool useDots = false)
181+
{
182+
const string suffix = "...";
183+
var truncatedString = text ?? string.Empty;
184+
185+
if (maxLength.IsLessOrEqualZero()) return truncatedString;
186+
var strLength = maxLength - (useDots.Equals(true) ? suffix.Length : 0);
187+
188+
if (strLength.IsLessOrEqualZero()) return truncatedString;
189+
190+
if (text.IsNullOrEmpty() || text!.Length <= maxLength) return truncatedString;
191+
192+
truncatedString = text.Substring(text.Length - strLength, strLength);
193+
truncatedString = truncatedString.TrimEnd();
194+
195+
if (useDots.IsTrue())
196+
return suffix + truncatedString;
197+
198+
return truncatedString;
199+
}
200+
173201
/// <summary>
174202
/// Truncate string by custom length
175203
/// </summary>
@@ -1647,7 +1675,6 @@ public static string IfNotStartsWith(this string source, string searchValue, str
16471675
return source.StartsWith(searchValue).IsFalse() ? resultValue : source;
16481676
}
16491677

1650-
16511678
/// <summary>
16521679
/// Check if string is in BASE32 format
16531680
/// </summary>

src/shared/GeneralAssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@
4747
[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
4848
#endif
4949

50-
[assembly: AssemblyVersion("3.2.0.4113")]
51-
[assembly: AssemblyFileVersion("3.2.0.4113")]
52-
[assembly: AssemblyInformationalVersion("3.2.0.4113")]
50+
[assembly: AssemblyVersion("3.3.0.5249")]
51+
[assembly: AssemblyFileVersion("3.3.0.5249")]
52+
[assembly: AssemblyInformationalVersion("3.3.0.5249")]

src/tests/DataTypeTests/DataTests/DateTimeTests.cs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,5 +323,93 @@ public void Epoch_Test()
323323
Assert.IsNotNull(epoch);
324324
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), epoch);
325325
}
326+
327+
[DataRow("2025-04-11 12:14:55.001", false)]
328+
[DataRow("2025-04-11 00:00:00.001", false)]
329+
[DataRow("2025-04-11 00:00:00.000", true)]
330+
[DataRow("2025-04-11 00:00:00", true)]
331+
[DataRow("2025-04-11", true)]
332+
[TestMethod]
333+
public void IsOnlyDate_Test(string date, bool resultExcepted)
334+
{
335+
var dateTime = Convert.ToDateTime(date);
336+
337+
var isDateOnly = dateTime.IsOnlyDate();
338+
339+
Assert.IsNotNull(isDateOnly);
340+
Assert.AreEqual(resultExcepted, isDateOnly);
341+
}
342+
343+
[DataRow("2025-04-11 12:14:55.001", false)]
344+
[DataRow("2025-04-11 00:00:00.001", false)]
345+
[DataRow("2025-04-11 00:00:00.000", true)]
346+
[DataRow("2025-04-11 00:00:00", true)]
347+
[DataRow("2025-04-11", true)]
348+
[TestMethod]
349+
public void IsOnlyDate_Nullable_Test(string date, bool resultExcepted)
350+
{
351+
var dateTime = (DateTime?)Convert.ToDateTime(date);
352+
353+
var isDateOnly = dateTime.IsOnlyDate();
354+
355+
Assert.IsNotNull(isDateOnly);
356+
Assert.AreEqual(resultExcepted, isDateOnly);
357+
}
358+
359+
[DataRow("2025-04-11 12:14:55.001", "2025-04-11 12:14:55.000")]
360+
[DataRow("2025-04-11 00:00:00.001", "2025-04-11 00:00:00.000")]
361+
[DataRow("2025-04-11 00:00:00.000", "2025-04-11 00:00:00.000")]
362+
[DataRow("2025-04-11 00:00:00", "2025-04-11 00:00:00.000")]
363+
[DataRow("2025-04-11", "2025-04-11 00:00:00.000")]
364+
[TestMethod]
365+
public void ForceMillisecondsToZero_Test(string date, string resultExcepted)
366+
{
367+
var dateTime = (DateTime)Convert.ToDateTime(date);
368+
var exceptedDateTime = (DateTime)Convert.ToDateTime(resultExcepted);
369+
370+
var newDateTime = dateTime.ForceMillisecondsToZero();
371+
372+
Assert.IsNotNull(newDateTime);
373+
Assert.AreEqual(exceptedDateTime, newDateTime);
374+
}
375+
376+
[DataRow("2025-04-11 12:14:55.001", "2025-04-11 12:14:55.000")]
377+
[DataRow("2025-04-11 00:00:00.001", "2025-04-11 00:00:00.000")]
378+
[DataRow("2025-04-11 00:00:00.000", "2025-04-11 00:00:00.000")]
379+
[DataRow("2025-04-11 00:00:00", "2025-04-11 00:00:00.000")]
380+
[DataRow("2025-04-11", "2025-04-11 00:00:00.000")]
381+
[TestMethod]
382+
public void ForceMillisecondsToZero_Nullable_Test(string date, string resultExcepted)
383+
{
384+
var dateTime = (DateTime?)Convert.ToDateTime(date);
385+
var exceptedDateTime = (DateTime?)Convert.ToDateTime(resultExcepted);
386+
387+
var newDateTime = dateTime.ForceMillisecondsToZero();
388+
389+
Assert.IsNotNull(newDateTime);
390+
Assert.AreEqual(exceptedDateTime, newDateTime);
391+
}
392+
393+
[DataRow("2025-04-11 12:14:55.001", "2025-04-11 12:14:55.000")]
394+
[DataRow("2025-04-11 00:00:00.001", "2025-04-11 00:00:00.000")]
395+
[DataRow("2025-04-11 00:00:00.000", "2025-04-11 00:00:00.000")]
396+
[DataRow("2025-04-11 00:00:00", "2025-04-11 00:00:00.000")]
397+
[DataRow("2025-04-11", "2025-04-11 00:00:00.000")]
398+
[DataRow("", "")]
399+
[TestMethod]
400+
public void ForceMillisecondsToZero_Nullable_WithDefaultDate_Test(string date, string resultExcepted)
401+
{
402+
var now = DateTime.Now;
403+
var dateTime = (DateTime?)Convert.ToDateTime(date.IfNullOrEmpty(now.ToString("yyyy-MM-dd HH:mm:ss")));
404+
var exceptedDateTime =
405+
date.IsNullOrEmpty()
406+
? now.ForceMillisecondsToZero()
407+
: (DateTime?)Convert.ToDateTime(resultExcepted);
408+
409+
var newDateTime = dateTime.ForceMillisecondsToZero(now);
410+
411+
Assert.IsNotNull(newDateTime);
412+
Assert.AreEqual(exceptedDateTime, newDateTime);
413+
}
326414
}
327415
}

src/tests/DataTypeTests/DataTests/GuidTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,37 @@ public void ToLongTest()
103103
Assert.AreEqual(5631682104563650436, res);
104104
Assert.AreEqual(0, res1);
105105
}
106+
107+
[TestMethod]
108+
public void NullIfEmpty_NullGuidValue_Test()
109+
{
110+
var result = ((Guid?)null).NullIfEmpty();
111+
112+
Assert.IsNull(result);
113+
}
114+
115+
[TestMethod]
116+
public void NullIfEmpty_EmptyGuidValue_Test()
117+
{
118+
var result = (Guid.Empty).NullIfEmpty();
119+
120+
Assert.IsNull(result);
121+
}
122+
123+
[TestMethod]
124+
public void EmptyIfNull_NullGuidValue_Test()
125+
{
126+
var result = ((Guid?)null).EmptyIfNull();
127+
128+
Assert.AreEqual(Guid.Empty, result);
129+
}
130+
131+
[TestMethod]
132+
public void EmptyIfNull_EmptyGuidValue_Test()
133+
{
134+
var result = (Guid.Empty).EmptyIfNull();
135+
136+
Assert.AreEqual(Guid.Empty, result);
137+
}
106138
}
107139
}

0 commit comments

Comments
 (0)