Search code examples
c#.netdatetimeparsing

.NET difference in DateTIme parsing


I'm using .NET 8 and I noticed that DateTime strings from requests are parsed differently in the query parameters and in the body.

I have made this example request to show the issue:

POST /api/Save?ValidFrom=2024-01-01T00:00:00+01:00

{
"validFrom":"2024-01-01T00:00:00+01:00"
}

As you can see the date in the query parameters and the body are identical. I'm using the ISO8601 format. The problem is, that now on the controller method the date from the query parameters is parsed as UTC Kind "31.12.2023 23:00:00" and the one from the body as Local Kind "01.01.2024 00:00:00".

[HttpPost]
public async Task<ActionResult<InstitutionContributionRecognitionModel>> SaveAsync(DateTime ValidFrom, [FromBody] Model model, CancellationToken cancellationToken)
{
    // ValidFrom = 31.12.2023 23:00:00
    // model.ValidFrom = 01.01.2024 00:00:00
}

Is there a way to use the same parsing behaviour in the query parameters? Only workaround I currently see is to use DateTimeOffset in the query parameter and then use the DateTimeOffset.DateTime to retrieve the client's local date.


Solution

  • Use DateTimeOffset so that the timezone information is preserved during parsing. So update your controller method to use DateTimeOffset. Something like this:

    [HttpPost]
    public async Task<ActionResult<InstitutionContributionRecognitionModel>> SaveAsync(
        DateTimeOffset ValidFrom,
        [FromBody] Model model,
        CancellationToken cancellationToken)
    {
        // Both ValidFrom and model.ValidFrom should be the same now.
    }
    

    Also, update your model to use DateTimeOffset, too.

    public class Model
    {
        public DateTimeOffset ValidFrom { get; set; }
    }