4

I'm having trouble with DateTimes in my ASP.NET C# Web Api 2 project. I need to pass through an ISO 8601 date in my query string as follows:

api/resource?at=2016-02-14T23:30:58Z

My controller method is as follows

[HttpGet("/resource")]
public IActionResult GetResource([FromQuery]DateTime? at = null)
{
    if (!at.HasValue)
    {
        at = DateTime.UtcNow;
    }
    else
    {
        at = DateTime.SpecifyKind(at.Value, DateTimeKind.Utc);
    }

    // ...
}

Notice the little hack - the date is coming in with a DateTimeKind of Local, despite being specified with the 'Z' signifying UTC. Dates should always be passed in UTC although I would ideally not like this to be a constraint. I am using NodaTime internally and only expose DateTime in the query and response models for legacy reasons.

  • Why are my dates parsed to a DateTimeKind of local?

  • How can I read my UTC dates from query strings using ASP.NET web api 2?

08Dc91wk
  • 4,254
  • 8
  • 34
  • 67

1 Answers1

4

If you use DateTimeOffset instead of DateTime, the time-zone offset is preserved. You could then either use it directly, or convert it to a DateTime via the UtcDateTime property.

 DateTimeOffset dto = DateTimeOffset.Parse("2016-02-14T23:30:58Z");
 DateTime dt = dto.UtcDateTime;

[HttpGet("/resource")]
public IActionResult GetResource([FromQuery]DateTimeOffset? at = null)
{
    if (!at.HasValue)
    {
        at = DateTimeOffset.UtcNow;
    }

    // ...
}
Markus Jarderot
  • 86,735
  • 21
  • 136
  • 138
  • 1
    Thanks Markus, that is the solution. Still find it odd that a DateTime query would simply ignore any time zone information when there is available a DateTimeKind.Utc and various local times, but this does cater for that. – 08Dc91wk Feb 15 '16 at 07:41