-
Please see the following C# test: using FluentAssertions;
using FluentAssertions.Extensions;
namespace Tests.Unit.Api;
[TestFixture]
[Category("Unit")]
public class Tests
{
[TestCase(1953,4,12,"21:53")] // fails
[TestCase(1953,2,12,"20:53")] // succeeds
[TestCase(2023,4,12,"21:53")] // succeeds
[TestCase(2023,2,12,"20:53")] // succeeds
public void WhyDoesThisFail(int year, int month, int day, string expectedTime)
{
// Arrange
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
var dateTime = new DateTime(year,month,day,19,53,3,DateTimeKind.Utc);
// Act
var result = TimeZoneInfo.ConvertTimeFromUtc(dateTime, timeZoneInfo);
// Assert
TimeOnly.FromDateTime(result).ToShortTimeString().Should().Be(expectedTime);
}
} When running this test on my Win11 machine both in Rider and Visual Studio or via But within my GitHub Action running on Failed WhyDoesThisFail [2 ms]
Error Message:
Expected TimeOnly.FromDateTime(result).ToShortTimeString() to be "21:53", but "20:53" differs near "0:5" (index 1). I already figured out that it seems to be related to daylight savings, but I'd like know...
Thx! Running on .NET |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 2 replies
-
Beta Was this translation helpful? Give feedback.
-
When I look at
I.e. Windows simplifies things and assumes that time zone always followed its current DST rules. On the other hand, on Linux (which uses the tzdb), there is no DST adjustment rule between 1949 and 1980, which seems to be correct (Germany did not observe DST during this period). So the Windows result is incorrect, but there's not much .Net can do about that, since it just takes the data from Windows. |
Beta Was this translation helpful? Give feedback.
-
You can't (and the test can break regardless). But you have a larger problem - unless you perform specific and involved setup, you don't control the data used during testing, which can cause your tests to break at any time, including on Linux. And if this is an application/library you provide to a third party, you aren't going to have control over it during application deployment. This is made more egregious by the fact that you're testing formatting output, which will in most cases be culture specific, which you also don't have control over. Unless you're controlling the test execution environment (ie, via a devcontainer or other tools), those tests will break when people in different places run them. So:
@mu88 - Is there a reason you're testing with these values? Or generally concerned with historical zones? If you actually need historical data like this, especially if you're doing heavy work with timezones, you will almost certainly need to use NodaTime, to cover the gaps in the in-box APIs. It will mean you need to maintain your own set of ICU datafiles, unfortunately, but will mean you can make the data consistent across OSes. |
Beta Was this translation helpful? Give feedback.
-
As indicated in other replies, .NET depends on Windows time zone data. Unfortunately, Windows TZ data does not include all historical data (like the year 1953 in such an example). So, there are some limitations on Windows. In the future releases we'll look at consuming TZ data from ICU which can give better historical data. When we do that, apps will get a better experience. |
Beta Was this translation helpful? Give feedback.
When I look at
timeZoneInfo.GetAdjustmentRules()
forEurope/Berlin
on Windows, I see:I.e. Windows simplifies things and assumes that time zone always followed its current DST rules.
On the other hand, on Linux (which uses the tzdb), there is no DST adjustment rule between 1949 and 1980, which seems to be correct (Germany did not observe DST during this period).
So the Windows result is incorrect, but there's not much .Net can do about that, since it just takes the data from Windows.