Search code examples
c#postgresqlasp.net-coreentity-framework-coreintegration-testing

ASP .NET Core & EF Core Integration Tests : unexpected datetime 1-Hour shift


I'm working on an ASP .NET Core 7 WebAPI, which handles Datetimes. I use Entity Framework Core 7 and Npgsql with Postgres. As I want to save Datetimes without timezones to the database, I use the switch on the AppContext to enable it, according to Npgsql docs. The issue is, in my integration test, everything is fine (date in response body is correct) until the date on the created record in the database, the Datetime object I get is shifted to 1 hour in the futur, event though, when I check in the database with a SQL Client, the date is correct. Here is the code of my integration test :


[Fact]
public async Task CreatePoll_CreatesPollInDb()
{
    // Given
    var createPollRequest = new CreatePollRequest
        ("Test Poll", DateTime.Now.AddDays(90), new List<DateTime> { DateTime.Now, DateTime.Now.AddDays(1) } );
    
    // When
    HttpResponseMessage response = await Client.PostAsJsonAsync("/api/polls", createPollRequest);
    
    // Then
    response.StatusCode.Should().Be(HttpStatusCode.Created);
    var pollFromResponse = await response.Content.ReadFromJsonAsync<Poll>();
    pollFromResponse.Id.Should().NotBeEmpty();
    pollFromResponse.Name.Should().Be(createPollRequest.Name);
    pollFromResponse.Dates.Should().BeEquivalentTo(createPollRequest.Dates);
    pollFromResponse.ExpirationDate.Should().Be(createPollRequest.ExpirationDate);
    
    Poll pollInDb = await DbContext.Polls.FirstAsync(record => record.Id == pollFromResponse.Id);
    pollInDb.Name.Should().Be(createPollRequest.Name);
    pollInDb.ExpirationDate.Should().Be(createPollRequest.ExpirationDate);
    pollInDb.Dates.Should().BeEquivalentTo(createPollRequest.Dates);
}

The DbContext used in the test is not the one of the application, it is created specifically for the test as a separate fixture. The test runs against a real postgres database running in Docker.


Solution

  • I believe these solutions would answers your question (.net) Unexpected offest when call DateTime.Today.AddDays

    DateTime.Now giving incorrect time

    I would like to recommend usingDateTime utcDate = DateTime.UtcNow;then change the datetime to users time. Like the 2nd link is recommending.

    Ps. This problem is not new, and has been discussed many times before. It's not a problem of EF or asp.net.core. It's a C# issue.

     public class Example
     {
     public static void Main()
     {
         DateTime localDate = DateTime.Now;
         String[] cultureNames = { "en-US", "en-GB", "fr-FR",
                                "de-DE", "ru-RU" };
    
         foreach (var cultureName in cultureNames) {
         var culture = new CultureInfo(cultureName);
         Console.WriteLine("{0}: {1}", cultureName,
                           localDate.ToString(culture));
      }
     }
    

    The example displays the following output: en-US: 6/19/2015 10:03:06 AM

    en-GB: 19/06/2015 10:03:06

    fr-FR: 19/06/2015 10:03:06

    de-DE: 19.06.2015 10:03:06

    ru-RU: 19.06.2015 10:03:06

    https://learn.microsoft.com/en-us/dotnet/api/system.datetime.now?view=net-7.0