Here are the editor and display templates that allow the user to enter and display the time in their own time zone and convert it to UTC for sending.
For the UIHint attribute for the user value "UTCTime" for each UTC field DateTime of the model, as shown below, to select the correct display templates and editor. DateTimes on models without this annotation will not execute:
[UIHint("UTCTime")] [DataType(DataType.DateTime)] public DateTime LastSeen { get; set; }
/Views/Shared/EditorTemplatesUTCTime.cshtml:
@model DateTime? @{ var name = Html.GetFieldNameForModel(); // See the HTML extension at the end of this post var boxName = name + ".Value"; var boxId = name + "_Value"; var divId = name + "_UTC"; } @Html.TextBoxFor(m => m.Value, new { type = "datetime", onBlur ="$('#" + name + "').val(UTCDateFuncs.ToUTCDate($('#" + boxId + "').val()));$('#" + divId + "').html('UTC:' + $('#" + name + "').val());$('#" + boxId + "').attr('title','UTC:' + $('#" + name + "').val());" })<span id="@divId"></span> <script> new function () { var utcVal = $('#@(boxId)').val(); $('#@(boxId)').val(UTCDateFuncs.FromUTCDate(utcVal)); $('#@(boxId)').attr('title', 'converted from UTC ' + utcVal); } </script> @Html.HiddenFor(m=>m)
\ Views \ Shared \ DisplayTemplates \ UTCTime.cshtml
@model DateTime? @if(Model.HasValue){<span class="UTCTime">@Model</span>}
Necessary javascript in the site template or somewhere (not in the template):
// UTC Date $(function () { $('.UTCTime').each(function () { var oldtext = $(this).html(); var result = UTCDateFuncs.FromUTCDate(oldtext); $(this).html(result); $(this).attr("title", "Converted from UTC " + oldtext); }); }); var UTCDateFuncs = { ToUTCDate: function (datetext) { try { var n = new Date(datetext); offsetms = n.getTimezoneOffset() * 60 * 1000; n = new Date(n.valueOf() + offsetms); result = n.toDateString() + " " + n.toLocaleTimeString(); } catch (ex) { console.warn("Error converting time", ex); } return result; }, FromUTCDate: function (datetext) { var result; try { var n = new Date(datetext); offsetms = n.getTimezoneOffset() * 60 * 1000; n = new Date(n.valueOf() - offsetms); result = n.toDateString() + " " + n.toLocaleTimeString(); } catch (ex) { console.warn("Error converting time", ex); } return result; } };
Also utilizes this HTML extension: \ Controllers \ Extensions \ HtmlExtensions.cs
using System; using System.Web.Mvc; public static class HtmlExtensions { public static string GetFieldNameForModel<TModel>(this HtmlHelper<TModel> htmlHelper) { var ti = htmlHelper.ViewData.TemplateInfo; var name = ti.HtmlFieldPrefix; return name; } }
This is used exclusively on our administrative pages, therefore, after the text field, a not very convenient interface is displayed that shows the conversion result for the editor window.