You can't do ToLocalTime() on the server since the server is in UTC. You either need to:
- Have the client somehow send up it's timezone (this can be tricky since you won't get it by default with a GET request)
- Have the server send down UTC and the client converts it to the local time. This happens naturally if you're using AJAX, but is cumbersome with just a razor view:
Here's a trick I used for to make the 2nd approach very easy for Razor views:
The server renders elements with a special class ".mytime" and the utc time (from server) specified in a custom attribute "utc":
<div class="mytime" utc ="@date.ToString("o")"></div>
<span class="mytime" utc ="2018-12-28T02:36:13.6774675Z"></span>
Note that .ToString("o") is how to write in UTC time.
And then have a local jQuery function iterate through all the elements with "mytime" class, read the UTC value in the attribute, and then do the conversion.
$(function () {
var key = $(".mytime").each(function (i, obj) {
var element = $(this); // <div> or <span> element.
var utc = element.attr("utc"); // "2018-12-28T02:36:13.6774675Z"
var d = new Date(utc);
var l = d.toLocaleString(); // Runs client side, so will be client's local time!
element.text(l);
});
});
I then created a MVC razor helper for rendering:
public static MvcHtmlString LocalDate(this HtmlHelper helper, DateTime date)
{
// Must use MvcHtmlString to avoid encoding.
return new MvcHtmlString(String.Format("<span class=\"mytime\" utc =\"{0}\"></span>", date.ToString("o")));
}
So now my view just includes JQuery and script above and then does:
Created at @Html.LocalDate(Model.CreatedDate)
Since this is invoked in jQuery's $() onload, it runs after the server has sent down all the times.
Worked like a charm!