Skip to content

Commit

Permalink
Refactor TimeZoneConverter to remove NodaTime dependency
Browse files Browse the repository at this point in the history
* Refactor the `TimeZoneConverter` class to eliminate dependencies on the `NodaTime` library, now using `TimeZoneInfo` from NET8.0 framework.
* Simplify the constructor to require only an IANA timezone ID and an optional `CultureInfo` object.
* Update `ToZonedTime` and `ToUtc` methods for timezone conversions using `TimeZoneInfo`.
* Replace `ZonedTime` return value with `IZonedTimeInfo` interface.
* Remove `NodaTime` package reference from `Axuno.Tools.csproj`.
* Add `GetSystemTimeZoneList`, `GetIanaTimeZoneList`, and `CanMapToIanaTimeZone` methods.
* Update `IZonedTimeInfo` interface with additional properties and fully qualified names.
* Update test methods to `TimeZoneConverterTests` for handling unknown timezone IDs and default culture usage.
* Update `TimeZoneConverterTests` to reflect the refactored `TimeZoneConverter` class.
* Bump version to v7.2.1
  • Loading branch information
axunonb committed Oct 1, 2024
1 parent 1253ec4 commit a4f122f
Show file tree
Hide file tree
Showing 17 changed files with 158 additions and 241 deletions.
46 changes: 36 additions & 10 deletions Axuno.Tools.Tests/DateAndTime/TimeZoneConverterTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Globalization;
using NUnit.Framework;
using NodaTime;

namespace Axuno.Tools.Tests.DateAndTime;

Expand All @@ -9,14 +8,33 @@ public class TimeZoneConverterTests
{
private static Axuno.Tools.DateAndTime.TimeZoneConverter GetTimeZoneConverter(string culture)
{
var tzc = new Axuno.Tools.DateAndTime.TimeZoneConverter(
new NodaTime.TimeZones.DateTimeZoneCache(NodaTime.TimeZones.TzdbDateTimeZoneSource.Default),
"Europe/Berlin",
CultureInfo.GetCultureInfo(culture),
NodaTime.TimeZones.Resolvers.LenientResolver);
var tzc = new Axuno.Tools.DateAndTime.TimeZoneConverter("Europe/Berlin", CultureInfo.GetCultureInfo(culture));
return tzc;
}

[Test]
public void UnknownTimeZoneId_ShouldThrow()
{
// Act, Assert
Assert.That(() =>
{
_ = new Axuno.Tools.DateAndTime.TimeZoneConverter("unknown-time-zone", CultureInfo.CurrentCulture);
}, Throws.Exception.TypeOf<TimeZoneNotFoundException>());
}

[Test]
public void UseCurrentCulture_IfCultureIsMissing()
{
// Arrange
var utcDateTime = new DateTime(2022, 1, 1, 12, 0, 0, DateTimeKind.Utc);

// Act
var convertedDateTime = new Axuno.Tools.DateAndTime.TimeZoneConverter("Europe/Berlin").ToZonedTime(utcDateTime)!;

// Assert
Assert.That(convertedDateTime.CultureInfo.TwoLetterISOLanguageName, Is.EqualTo(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName));
}

[Test]
public void ConvertUtcToTimeZoneStandard_ShouldReturnCorrectDateTime()
{
Expand All @@ -40,7 +58,7 @@ public void ConvertUtcToTimeZoneStandard_ShouldReturnCorrectDateTime()
Assert.That(convertedDateTime.Abbreviation, Is.EqualTo("MEZ"));
Assert.That(convertedDateTime.IsDaylightSavingTime, Is.False);
Assert.That(convertedDateTime.DateTimeOffset.Offset, Is.EqualTo(new TimeSpan(0, 1, 0, 0)));
Assert.That(convertedDateTime.BaseUtcOffset, Is.EqualTo(new TimeSpan(0,1,0,0)));
Assert.That(convertedDateTime.BaseUtcOffset, Is.EqualTo(new TimeSpan(0, 1, 0, 0)));
});
}

Expand Down Expand Up @@ -173,14 +191,22 @@ public void ConvertTimeZoneToUtc_ShouldReturnNull_WhenDateTimeOfAnyKindIsNull()
// Assert
Assert.That(convertedDateTime, Is.Null);
}

[Test]
public void GetTimeZoneList_ShouldReturnTimeZoneList_WhenTimeZoneProviderIsNull()
{
// Arrange
IDateTimeZoneProvider? timeZoneProvider = null;
// Act
var timeZoneList = Axuno.Tools.DateAndTime.TimeZoneConverter.GetSystemTimeZoneList();

// Assert
Assert.That(timeZoneList, Is.InstanceOf<IReadOnlyCollection<string>>());
}

[Test]
public void GetIanaTimeZoneList_ShouldReturnTimeZoneList_WhenTimeZoneProviderIsNull()
{
// Act
var timeZoneList = Axuno.Tools.DateAndTime.TimeZoneConverter.GetTimeZoneList(timeZoneProvider);
var timeZoneList = Axuno.Tools.DateAndTime.TimeZoneConverter.GetIanaTimeZoneList();

// Assert
Assert.That(timeZoneList, Is.InstanceOf<IReadOnlyCollection<string>>());
Expand Down
1 change: 0 additions & 1 deletion Axuno.Tools/Axuno.Tools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NodaTime" Version="3.1.12" />
<PackageReference Include="NuGetizer" Version="1.2.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
15 changes: 10 additions & 5 deletions Axuno.Tools/DateAndTime/IZonedTimeInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,20 @@ namespace Axuno.Tools.DateAndTime;
public interface IZonedTimeInfo
{
/// <summary>
/// Gets the <see cref="CultureInfo"/> used for localization.
/// Gets the <see cref="System.Globalization.CultureInfo"/> used for localization.
/// </summary>
CultureInfo CultureInfo { get; }

/// <summary>
/// Gets the IANA timezone ID related to the <see cref="DateTimeOffset"/>.
/// Gets the IANA timezone ID related to the <see cref="System.DateTimeOffset"/>.
/// </summary>
string TimeZoneId { get; }

/// <summary>
/// Gets the <see cref="System.DateTimeOffset"/> which is set based on the timezone offset to UTC.
/// </summary>
DateTimeOffset DateTimeOffset { get; }

/// <summary>
/// Gets the generic name for the time zone.
/// </summary>
Expand All @@ -33,17 +38,17 @@ public interface IZonedTimeInfo
string DisplayName { get; }

/// <summary>
/// Gets the name of the timezone related to the <see cref="DateTimeOffset"/>.
/// Gets the name of the timezone related to the <see cref="System.DateTimeOffset"/>.
/// </summary>
string Name { get; }

/// <summary>
/// Gets the timezone abbreviation related to the <see cref="DateTimeOffset"/>.
/// Gets the timezone abbreviation related to the <see cref="System.DateTimeOffset"/>.
/// </summary>
string Abbreviation { get; }

/// <summary>
/// Gets whether the timezone related to the <see cref="DateTimeOffset"/> is daylight saving time.
/// Gets whether the timezone related to the <see cref="System.DateTimeOffset"/> is daylight saving time.
/// </summary>
bool IsDaylightSavingTime { get; }

Expand Down
Loading

0 comments on commit a4f122f

Please sign in to comment.