Skip to content

Instantly share code, notes, and snippets.

@skolima
Last active March 31, 2020 15:56
Show Gist options
  • Save skolima/bc48bd708c322e6b97c494008d1c2a66 to your computer and use it in GitHub Desktop.
Save skolima/bc48bd708c322e6b97c494008d1c2a66 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using Xunit;
namespace DaylightSavingTimeTests
{
public class DstCalculationsTests
{
[Theory]
[MemberData(nameof(DstTestCases))]
public void ShouldCalculateTimeDifferenceAsExpected(
DateTimeOffset from,
DateTimeOffset until,
TimeSpan expectedDifference,
string description)
{
Assert.Equal(expectedDifference, until - from, new TimeSpanWithMillisecondPrecisionComparer(5));
}
public static TheoryData<DateTimeOffset, DateTimeOffset, TimeSpan, string> DstTestCases()
{
var utcDayBeforeGermanDst = new DateTimeOffset(2020, 3, 28, 11, 30, 00, TimeSpan.Zero);
var utcDayAfterGermanDst = new DateTimeOffset(2020, 3, 29, 15, 17, 00, TimeSpan.Zero);
var utcDayBeforePolishWinterTime = new DateTimeOffset(2019, 10, 26, 13, 45, 55, TimeSpan.Zero);
return new TheoryData<DateTimeOffset, DateTimeOffset, TimeSpan, string>
{
{DateTimeOffset.Now, DateTimeOffset.UtcNow, TimeSpan.FromHours(0), "UtcNow and Now"},
{DateTimeOffset.Now, DateTimeOffset.Now.AddHours(1), TimeSpan.FromHours(1), "One hour ahead, local time"},
{DateTimeOffset.Now, DateTimeOffset.Now.AddDays(1), TimeSpan.FromHours(24), "One day ahead, local time"},
{
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDayBeforeGermanDst, "Central Europe Standard Time"),
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDayBeforeGermanDst.AddDays(1), "Central Europe Standard Time"),
TimeSpan.FromHours(24),
"One day ahead, across DST start in Germany"
},
{
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDayAfterGermanDst, "Central Europe Standard Time"),
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDayAfterGermanDst.AddDays(-2), "Central Europe Standard Time"),
TimeSpan.FromHours(-48),
"Two days back, across DST start in Germany"
},
{
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDayBeforePolishWinterTime, "Central Europe Standard Time"),
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcDayBeforePolishWinterTime.AddDays(2), "Central Europe Standard Time"),
TimeSpan.FromHours(48),
"Two days ahead, across DST end in Poland"
},
};
}
}
public class TimeSpanWithMillisecondPrecisionComparer : IEqualityComparer<TimeSpan>
{
private readonly int _millisecondPrecision;
public TimeSpanWithMillisecondPrecisionComparer(int millisecondPrecision)
{
this._millisecondPrecision = millisecondPrecision;
}
public bool Equals(TimeSpan x, TimeSpan y)
{
var diff = (x - y).TotalMilliseconds;
return Math.Abs(diff) < this._millisecondPrecision;
}
public int GetHashCode(TimeSpan obj)
{
return obj.GetHashCode();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment