Skip to content

Commit 9ba05d0

Browse files
authored
Merge pull request #42 from sharpcode-it/engineering87-develop
Add some new DateTime helpers
2 parents b717546 + 317f3cf commit 9ba05d0

File tree

4 files changed

+288
-49
lines changed

4 files changed

+288
-49
lines changed

SharpHelpers/SharpHelpers.UnitTest/DateAndTime/DateTimeTest.cs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
// (c) 2023 SharpCoding
22
// This code is licensed under MIT license (see LICENSE.txt for details)
3-
43
using System;
54
using Microsoft.VisualStudio.TestTools.UnitTesting;
65
using SharpCoding.SharpHelpers;
76
using System.Linq;
87

9-
108
namespace SharpHelpers.UnitTest.DateAndTime
119
{
12-
13-
1410
[TestClass]
1511
public class DateTimeTest
1612
{
@@ -33,9 +29,49 @@ public void TestDateTimeSmart()
3329
}
3430

3531
DateTime dt1 = (DateTimeSmart)"01-05-2023 22:30:55";
36-
Assert.IsTrue(dt1 == new DateTime( 2023, 5, 1, 22, 30, 55, DateTimeKind.Local));
32+
Assert.IsTrue(dt1 == new DateTime(2023, 5, 1, 22, 30, 55, DateTimeKind.Local));
33+
}
3734

35+
[TestMethod]
36+
public void IsLeapYear_ShouldReturnTrueForLeapYear()
37+
{
38+
var leapYear = new DateTime(2024, 1, 1);
39+
var isLeapYear = leapYear.IsLeapYear();
40+
41+
Assert.IsTrue(isLeapYear);
3842
}
3943

44+
[TestMethod]
45+
public void Age_ShouldCalculateCorrectAge()
46+
{
47+
var birthDate = new DateTime(1990, 8, 18);
48+
var today = new DateTime(2024, 8, 18);
49+
var expectedAge = 34;
50+
51+
var age = birthDate.Age();
52+
53+
Assert.AreEqual(expectedAge, age);
54+
}
55+
56+
[TestMethod]
57+
public void AddBusinessDays_ShouldSkipWeekends()
58+
{
59+
var startDate = new DateTime(2024, 8, 16); // Friday
60+
var expected = new DateTime(2024, 8, 20); // 2 business days later (Tuesday)
61+
62+
var result = startDate.AddBusinessDays(2);
63+
64+
Assert.AreEqual(expected, result);
65+
}
66+
67+
[TestMethod]
68+
public void IsWeekend_ShouldReturnFalseForWeekday()
69+
{
70+
var monday = new DateTime(2024, 8, 19);
71+
72+
var isMondayWeekend = monday.IsWeekend();
73+
74+
Assert.IsFalse(isMondayWeekend);
75+
}
4076
}
4177
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// (c) 2019 SharpCoding
2+
// This code is licensed under MIT license (see LICENSE.txt for details)
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using SharpCoding.SharpHelpers;
5+
6+
namespace SharpHelpers.UnitTest.Regex
7+
{
8+
[TestClass]
9+
public class RegexTests
10+
{
11+
[TestMethod]
12+
public void IsMatch_ShouldReturnTrue_WhenPatternMatches()
13+
{
14+
// Arrange
15+
string input = "hello world";
16+
string pattern = @"hello";
17+
18+
// Act
19+
bool result = input.IsMatchRegex(pattern);
20+
21+
// Assert
22+
Assert.IsTrue(result, "Expected the pattern to match the input string.");
23+
}
24+
25+
[TestMethod]
26+
public void IsMatch_ShouldReturnFalse_WhenPatternDoesNotMatch()
27+
{
28+
// Arrange
29+
string input = "hello world";
30+
string pattern = @"goodbye";
31+
32+
// Act
33+
bool result = input.IsMatchRegex(pattern);
34+
35+
// Assert
36+
Assert.IsFalse(result, "Expected the pattern not to match the input string.");
37+
}
38+
39+
[TestMethod]
40+
public void Match_ShouldReturnFirstMatch_WhenPatternMatches()
41+
{
42+
// Arrange
43+
string input = "hello world";
44+
string pattern = @"hello";
45+
46+
// Act
47+
string result = input.Match(pattern);
48+
49+
// Assert
50+
Assert.AreEqual("hello", result, "Expected the first match to be 'hello'.");
51+
}
52+
53+
[TestMethod]
54+
public void Match_ShouldReturnNull_WhenPatternDoesNotMatch()
55+
{
56+
// Arrange
57+
string input = "hello world";
58+
string pattern = @"goodbye";
59+
60+
// Act
61+
string result = input.Match(pattern);
62+
63+
// Assert
64+
Assert.IsNull(result, "Expected no match to be found.");
65+
}
66+
67+
[TestMethod]
68+
public void Replace_ShouldReplaceAllOccurrences_WhenPatternMatches()
69+
{
70+
// Arrange
71+
string input = "hello world world";
72+
string pattern = @"world";
73+
string replacement = "universe";
74+
75+
// Act
76+
string result = input.Replace(pattern, replacement);
77+
78+
// Assert
79+
Assert.AreEqual("hello universe universe", result, "Expected 'world' to be replaced with 'universe'.");
80+
}
81+
82+
[TestMethod]
83+
public void Split_ShouldReturnArray_WhenPatternIsUsedAsDelimiter()
84+
{
85+
// Arrange
86+
string input = "hello world universe";
87+
string pattern = @" ";
88+
89+
// Act
90+
string[] result = input.Split(pattern);
91+
92+
// Assert
93+
CollectionAssert.AreEqual(new[] { "hello", "world", "universe" }, result, "Expected the input string to be split by spaces.");
94+
}
95+
}
96+
}
Lines changed: 101 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// (c) 2019 SharpCoding
22
// This code is licensed under MIT license (see LICENSE.txt for details)
33
using System;
4-
using System.Globalization;
5-
4+
using System.Globalization;
5+
66
namespace SharpCoding.SharpHelpers
77
{
88
public static class DateTimeHelper
@@ -46,56 +46,114 @@ public static DateTime AbsoluteEnd(this DateTime dateTime)
4646
public static DateTime? ToUniversalTime(this DateTime? dateTime)
4747
{
4848
return dateTime?.ToUniversalTime();
49-
}
50-
51-
/// <summary>
52-
/// Return the start of the current day
53-
/// </summary>
54-
/// <param name="dateTime"></param>
55-
/// <returns></returns>
56-
public static DateTime GetStartOfDay(this DateTime dateTime)
57-
{
58-
return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, 0);
5949
}
6050

61-
/// <summary>
62-
/// Return the end of the current day
63-
/// </summary>
64-
/// <param name="dateTime"></param>
51+
/// <summary>
52+
/// Return the start of the current day
53+
/// </summary>
54+
/// <param name="dateTime"></param>
6555
/// <returns></returns>
66-
public static DateTime GetEndOfDay(this DateTime dateTime)
67-
{
68-
return new DateTime(dateTime.Year, dateTime.Month,
69-
dateTime.Day, 23, 59, 59, 999);
56+
public static DateTime GetStartOfDay(this DateTime dateTime)
57+
{
58+
return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, 0);
7059
}
7160

72-
/// <summary>
73-
/// Try to parse the string value with specific DateTime formats
74-
/// </summary>
75-
/// <param name="value"></param>
76-
/// <param name="formats"></param>
61+
/// <summary>
62+
/// Return the end of the current day
63+
/// </summary>
64+
/// <param name="dateTime"></param>
7765
/// <returns></returns>
78-
public static DateTime? AsDateTime(this string value, string[] formats)
79-
{
80-
if (DateTime.TryParseExact(value, formats, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind,
81-
out DateTime utcDateTime))
82-
{
83-
return utcDateTime;
84-
}
85-
86-
return null;
66+
public static DateTime GetEndOfDay(this DateTime dateTime)
67+
{
68+
return new DateTime(dateTime.Year, dateTime.Month,
69+
dateTime.Day, 23, 59, 59, 999);
8770
}
8871

89-
/// <summary>
90-
/// Check if a date is between two dates
91-
/// </summary>
92-
/// <param name="dt"></param>
93-
/// <param name="rangeBeg"></param>
94-
/// <param name="rangeEnd"></param>
72+
/// <summary>
73+
/// Try to parse the string value with specific DateTime formats
74+
/// </summary>
75+
/// <param name="value"></param>
76+
/// <param name="formats"></param>
77+
/// <returns></returns>
78+
public static DateTime? AsDateTime(this string value, string[] formats)
79+
{
80+
if (DateTime.TryParseExact(value, formats, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind,
81+
out DateTime utcDateTime))
82+
{
83+
return utcDateTime;
84+
}
85+
86+
return null;
87+
}
88+
89+
/// <summary>
90+
/// Check if a date is between two dates
91+
/// </summary>
92+
/// <param name="dt"></param>
93+
/// <param name="rangeBeg"></param>
94+
/// <param name="rangeEnd"></param>
95+
/// <returns></returns>
96+
public static bool IsBetween(this DateTime dt, DateTime rangeBeg, DateTime rangeEnd)
97+
{
98+
return dt.Ticks >= rangeBeg.Ticks && dt.Ticks <= rangeEnd.Ticks;
99+
}
100+
101+
/// <summary>
102+
/// Check if a day is a weekend.
103+
/// </summary>
104+
/// <param name="dateTime"></param>
95105
/// <returns></returns>
96-
public static bool IsBetween(this DateTime dt, DateTime rangeBeg, DateTime rangeEnd)
97-
{
98-
return dt.Ticks >= rangeBeg.Ticks && dt.Ticks <= rangeEnd.Ticks;
106+
public static bool IsWeekend(this DateTime dateTime)
107+
{
108+
return dateTime.DayOfWeek == DayOfWeek.Saturday || dateTime.DayOfWeek == DayOfWeek.Sunday;
109+
}
110+
111+
/// <summary>
112+
/// Add business days to a DateTime.
113+
/// </summary>
114+
/// <param name="dateTime"></param>
115+
/// <param name="businessDays"></param>
116+
/// <returns></returns>
117+
public static DateTime AddBusinessDays(this DateTime dateTime, int businessDays)
118+
{
119+
if (businessDays == 0)
120+
return dateTime;
121+
122+
int direction = businessDays > 0 ? 1 : -1;
123+
int daysToAdd = Math.Abs(businessDays);
124+
125+
while (daysToAdd > 0)
126+
{
127+
dateTime = dateTime.AddDays(direction);
128+
if (!dateTime.IsWeekend())
129+
daysToAdd--;
130+
}
131+
132+
return dateTime;
133+
}
134+
135+
/// <summary>
136+
/// Return the age of a person.
137+
/// </summary>
138+
/// <param name="birthDate"></param>
139+
/// <returns></returns>
140+
public static int Age(this DateTime birthDate)
141+
{
142+
var today = DateTime.Today;
143+
var age = today.Year - birthDate.Year;
144+
if (birthDate.Date > today.AddYears(-age)) age--;
145+
return age;
146+
}
147+
148+
/// <summary>
149+
/// Check if the year is a leap year.
150+
/// </summary>
151+
/// <param name="dateTime"></param>
152+
/// <returns></returns>
153+
public static bool IsLeapYear(this DateTime dateTime)
154+
{
155+
int year = dateTime.Year;
156+
return DateTime.IsLeapYear(year);
99157
}
100158
}
101159
}

SharpHelpers/SharpHelpers/RegexHelper.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// (c) 2019 SharpCoding
22
// This code is licensed under MIT license (see LICENSE.txt for details)
3+
using System;
34
using System.Text.RegularExpressions;
45

56
namespace SharpCoding.SharpHelpers
@@ -14,8 +15,56 @@ public static class RegexHelper
1415
/// <returns></returns>
1516
public static bool IsMatchRegex(this string value, string pattern)
1617
{
18+
if (value == null) throw new ArgumentNullException(nameof(value));
19+
if (pattern == null) throw new ArgumentNullException(nameof(pattern));
20+
1721
var regex = new Regex(pattern);
18-
return (regex.IsMatch(value));
22+
return regex.IsMatch(value);
23+
}
24+
25+
/// <summary>
26+
/// Retrieves the first match found in the input string.
27+
/// </summary>
28+
/// <param name="input">The input string to search.</param>
29+
/// <param name="pattern">The regular expression pattern.</param>
30+
/// <returns>The first match found, or null if no match is found.</returns>
31+
public static string Match(this string input, string pattern)
32+
{
33+
if (input == null) throw new ArgumentNullException(nameof(input));
34+
if (pattern == null) throw new ArgumentNullException(nameof(pattern));
35+
36+
var match = Regex.Match(input, pattern);
37+
return match.Success ? match.Value : null;
38+
}
39+
40+
/// <summary>
41+
/// Replaces all occurrences of a pattern with a replacement string.
42+
/// </summary>
43+
/// <param name="input">The input string to modify.</param>
44+
/// <param name="pattern">The regular expression pattern.</param>
45+
/// <param name="replacement">The replacement string.</param>
46+
/// <returns>A new string with all occurrences replaced.</returns>
47+
public static string Replace(this string input, string pattern, string replacement)
48+
{
49+
if (input == null) throw new ArgumentNullException(nameof(input));
50+
if (pattern == null) throw new ArgumentNullException(nameof(pattern));
51+
if (replacement == null) throw new ArgumentNullException(nameof(replacement));
52+
53+
return Regex.Replace(input, pattern, replacement);
54+
}
55+
56+
/// <summary>
57+
/// Splits a string into an array of substrings using a regex pattern as a delimiter.
58+
/// </summary>
59+
/// <param name="input">The input string to split.</param>
60+
/// <param name="pattern">The regular expression pattern to use as a delimiter.</param>
61+
/// <returns>An array of substrings.</returns>
62+
public static string[] Split(this string input, string pattern)
63+
{
64+
if (input == null) throw new ArgumentNullException(nameof(input));
65+
if (pattern == null) throw new ArgumentNullException(nameof(pattern));
66+
67+
return Regex.Split(input, pattern);
1968
}
2069
}
2170
}

0 commit comments

Comments
 (0)