Reputation: 9568
I am developing a dot net core 2.2 console application to convert .csv files to .xml files.
I have a unit test to test the creation of a specific xml filename. Part of the filename is a time. This timepart should always be a local time. Using dotnet core 2.2 with xUnit.
The test succeeds locally (Netherlands, culture nl-NL), but fails when testing in Azure using a Hosting Agent. This Hosting Agent is hosted somewhere in the US (culture en-US).
To fix this test, I created a specific run scope in a specific culture. I assumed that the .LocalTime of the DateTimeOffset gives me the culture specific local time, but it stays in nl-NL when I debug it in VS2019.
Why ?
Here are some code parts (removed some code for better reading):
public class OutputIdentifierServiceTests
{
[Fact(DisplayName = "Valid filename is created")]
public void GetOutputIdentifier_ReturnsFilename()
{
// Arrange
// utc time = 16:52:33
// local nl-NL time = 18:52:33
using (new CurrentCultureScope("en-US"))
{
var currentTimeUtc = new DateTimeOffset(2019, 6, 14, 16, 52, 33, TimeSpan.Zero);
_systemClockServiceMock.SetupGet(s => s.UtcNow).Returns(currentTimeUtc);
var sut = CreateSut();
// Act
var filename = sut.GetOutputIdentifier();
// Assert
Assert.Equal("20190614T165233", filename);
}
}
}
And the CurrentCultureScope class:
public class CurrentCultureScope : IDisposable
{
private readonly CultureInfo _culture;
private readonly CultureInfo _uiCulture;
private bool _disposed = false;
public CurrentCultureScope(string name)
{
_culture = Thread.CurrentThread.CurrentCulture;
_uiCulture = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo(name);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(name);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
Thread.CurrentThread.CurrentCulture = _culture;
Thread.CurrentThread.CurrentUICulture = _uiCulture;
}
_disposed = true;
}
}
}
}
And the class creating the output identifier:
public string GetOutputIdentifier()
{
var currentTimeUtc = _systemClockService.UtcNow;
var localTime = currentTimeUtc.LocalDateTime;
var creationDate = localTime.ToString("yyyyMMdd");
var creationTime = localTime.ToString("HHmmss");
// code removed
}
Upvotes: 1
Views: 2655
Reputation: 9568
I fixed it in the output identifier function (thanks to Panagiotis Kanavos, see comments). The CurrentCultureScope is not needed.
var currentTimeUtc = _systemClockService.UtcNow;
var nlZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
var localTime = TimeZoneInfo.ConvertTime(currentTimeUtc, nlZone);
Upvotes: 1