Skip to content

Commit

Permalink
Add DateOnly and DateTimeOffset extension methods (#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcominerva authored Jun 19, 2024
2 parents 840ee77 + 525e5cc commit 8ebe596
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.5" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.6" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.133" PrivateAssets="All" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.139" PrivateAssets="All" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/TinyHelpers.AspNetCore/TinyHelpers.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.2" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.30" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.31" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.20" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.6" />
</ItemGroup>

<ItemGroup>
Expand Down
25 changes: 25 additions & 0 deletions src/TinyHelpers/Extensions/DateOnlyExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace TinyHelpers.Extensions;

#if NET6_0_OR_GREATER
/// <summary>
/// Contains extension methods for the <see cref="DateOnly"/> type.
/// </summary>
/// <seealso cref="DateOnly"/>
public static class DateOnlyExtensions
{
/// <summary>
/// Converts a <see cref="DateOnly"/> value to a <see cref="DateTimeOffset"/> value.
/// </summary>
/// <param name="dateOnly">The <see cref="DateOnly"/> value to convert.</param>
/// <param name="zone">The optional <see cref="TimeZoneInfo"/> to apply to the resulting <see cref="DateTimeOffset"/> value.</param>
/// <returns>The converted <see cref="DateTimeOffset"/> value.</returns>
/// <seealso cref="DateOnly"/>
/// <seealso cref="DateTimeOffset"/>
/// <seealso cref="TimeZoneInfo"/>
public static DateTimeOffset ToDateTimeOffset(this DateOnly dateOnly, TimeZoneInfo? zone = null)
{
var dateTime = dateOnly.ToDateTime(TimeOnly.MinValue);
return new DateTimeOffset(dateTime, zone?.GetUtcOffset(dateTime) ?? TimeSpan.Zero);
}
}
#endif
10 changes: 0 additions & 10 deletions src/TinyHelpers/Extensions/DateTimeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,5 @@ public static DateOnly ToDateOnly(this DateTime dateTime)
/// <seealso cref="TimeOnly"/>
public static TimeOnly ToTimeOnly(this DateTime dateTime)
=> TimeOnly.FromDateTime(dateTime);

/// <summary>
/// Constructs a <see cref="TimeOnly"/> object from a <see cref="TimeSpan"/> representing the time elapsed since midnight.
/// </summary>
/// <param name="timeSpan">The time interval measured since midnight. This value has to be positive and not exceeding the time of the day.</param>
/// <returns>A <see cref="TimeOnly"/> object representing the time elapsed since midnight using the <paramref name="timeSpan"/> value.</returns>
/// <seealso cref="DateTime"/>
/// <seealso cref="TimeOnly"/>
public static TimeOnly ToTimeOnly(this TimeSpan timeSpan)
=> TimeOnly.FromTimeSpan(timeSpan);
#endif
}
40 changes: 40 additions & 0 deletions src/TinyHelpers/Extensions/DateTimeOffsetExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace TinyHelpers.Extensions;

/// <summary>
/// Contains extension methods for the <see cref="DateTimeOffset"/> type.
/// </summary>
/// <seealso cref="DateTimeOffset"/>
public static class DateTimeOffsetExtensions
{
#if NET6_0_OR_GREATER
/// <summary>
/// Constructs a <see cref="DateOnly"/> object that is set to the date part of the specified <see cref="DateTimeOffset"/>.
/// </summary>
/// <param name="dateTimeOffset">The <see cref="DateTimeOffset"/> object to extract the date part from.</param>
/// <param name="zone">The optional <see cref="TimeZoneInfo"/> to apply to the resulting <see cref="DateTimeOffset"/> value.</param>
/// <returns>A <see cref="DateOnly"/> object representing date of the day specified in the <paramref name="dateTimeOffset"/> object.</returns>
/// <seealso cref="DateTimeOffset"/>
/// <seealso cref="DateOnly"/>
/// <seealso cref="TimeZoneInfo"/>
public static DateOnly ToDateOnly(this DateTimeOffset dateTimeOffset, TimeZoneInfo? zone = null)
{
var inTargetZone = TimeZoneInfo.ConvertTime(dateTimeOffset, zone ?? TimeZoneInfo.Utc);
return DateOnly.FromDateTime(inTargetZone.Date);
}

/// <summary>
/// Constructs a <see cref="TimeOnly"/> object from a <see cref="DateTimeOffset"/> representing the time of the day in this <see cref="DateTimeOffset"/> object.
/// </summary>
/// <param name="dateTimeOffset">The <see cref="DateTimeOffset"/> object to extract the time of the day from.</param>
/// <param name="zone">The optional <see cref="TimeZoneInfo"/> to apply to the resulting <see cref="DateTimeOffset"/> value.</param>
/// <returns>A <see cref="TimeOnly"/> object representing time of the day specified in the <paramref name="dateTimeOffset"/> object.</returns>
/// <seealso cref="DateTimeOffset"/>
/// <seealso cref="TimeOnly"/>
/// <seealso cref="TimeZoneInfo"/>
public static TimeOnly ToTimeOnly(this DateTimeOffset dateTimeOffset, TimeZoneInfo? zone = null)
{
var inTargetZone = TimeZoneInfo.ConvertTime(dateTimeOffset, zone ?? TimeZoneInfo.Utc);
return TimeOnly.FromDateTime(dateTimeOffset.DateTime);
}
#endif
}
20 changes: 20 additions & 0 deletions src/TinyHelpers/Extensions/TimeSpanExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace TinyHelpers.Extensions;

/// <summary>
/// Contains extension methods for the <see cref="TimeSpan"/> type.
/// </summary>
/// <seealso cref="TimeSpan"/>
public static class TimeSpanExtensions
{
#if NET6_0_OR_GREATER
/// <summary>
/// Constructs a <see cref="TimeOnly"/> object from a <see cref="TimeSpan"/> representing the time elapsed since midnight.
/// </summary>
/// <param name="timeSpan">The time interval measured since midnight. This value has to be positive and not exceeding the time of the day.</param>
/// <returns>A <see cref="TimeOnly"/> object representing the time elapsed since midnight using the <paramref name="timeSpan"/> value.</returns>
/// <seealso cref="DateTime"/>
/// <seealso cref="TimeOnly"/>
public static TimeOnly ToTimeOnly(this TimeSpan timeSpan)
=> TimeOnly.FromTimeSpan(timeSpan);
#endif
}
49 changes: 49 additions & 0 deletions tests/TinyHelpers.Tests/Extensions/DateOnlyExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using FluentAssertions;
using TinyHelpers.Extensions;

namespace TinyHelpers.Tests.Extensions;

public class DateOnlyExtensionsTests
{
[Fact]
public void Should_Return_True1()
{
// Arrange
var input = new DateOnly(2020, 1, 1);
var result = new DateTimeOffset(2020, 1, 1, 0, 0, 0, TimeSpan.Zero);

// Act
var output = input.ToDateTimeOffset();

// Assert
output.Should().Be(result);
}

[Fact]
public void Should_Return_True2()
{
// Arrange
var input = new DateOnly(2023, 6, 12);
var result = new DateTimeOffset(2023, 6, 12, 0, 0, 0, TimeSpan.Zero);

// Act
var output = input.ToDateTimeOffset();

// Assert
output.Should().Be(result);
}

[Fact]
public void Should_Return_False()
{
// Arrange
var input = new DateOnly(2020, 1, 1);
var result = new DateTimeOffset(2020, 1, 1, 4, 0, 0, TimeSpan.Zero);

// Act
var output = input.ToDateTimeOffset();

// Assert
output.Should().NotBe(result);
}
}
4 changes: 2 additions & 2 deletions tests/TinyHelpers.Tests/Extensions/StringExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ public void ReplaceIgnoreCase_Should_Replace_Ignoring_Case(string input, string
[InlineData("marco", "Marco")]
[InlineData("mARCo", "MARCo")]
[InlineData("42", "42")]
public void FirstCharToUpper(string input, string expected)
public void FirstCharToUpper(string? input, string expected)
{
// Arrange

// Act
var newString = input.FirstCharToUpper();
var newString = input!.FirstCharToUpper();

// Assert
newString.Should().Be(expected);
Expand Down
10 changes: 5 additions & 5 deletions tests/TinyHelpers.Tests/TinyHelpers.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="xunit" Version="2.8.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down

0 comments on commit 8ebe596

Please sign in to comment.