November Happy Hour will be moved to Thursday December 5th.

How can I extend the PropertyFor to adjust a DateTime value?

Vote:
 

We are seeing some unexpected behavior with a DateTime control in the CMS that appears to stem from how DOJO and the browsers interpret UTC time.  For example, from the "On-Page Editing" context the DateTime field displays 1:00 PM. But when that field is selected to Edit, or if we toggle to the Content tab of the Properties view, the time shows up 6 hours later (7:00 PM).

For context, our servers are in one time zone, we are in a second time zone, and our clients are in a third time zone.  When they enter 1:00 PM we expect the CMS to display 1:00 PM in the "On-Page Editing" view and in the "Properties" view and in the DOJO date/time control.  The time needs to be consistent in all of these places, but presently it is not.

One approach I'm making to correct this is to extend the PropertyFor HTML helper to adjust the time displayed. So I created a helper called PropertyForDateTime, and from that helper I'm able to successfully capture the value that the field presents.  Now I need to add 6 hours to that value to make it align with the DOJO control. But I'm stuck on how to do that.

When debugging the solution I can see the property value in the Watch window under html.ViewData.Model.[MyPropertyName].  But I don't see a way to edit the value of that property.  What is the proper syntax or method of doing this?  My code is below.

If there is an easier or better way to tackle this time-discrepancy problem please let me know.  Thanks for your help.

public static MvcHtmlString PropertyForDateTime<>TModel, TValue>(
    this HtmlHelper<>TModel> html,
    Expression<>Func<>TModel, TValue>> expression)
{
    // Get the value 
    Func<>TModel, TValue> method = expression.Compile();
    TValue value = method(html.ViewData.Model);
 
    // Change value to new time.
    DateTime oldDateTime = (DateTime)(object)value;
    DateTime newDateTime = oldDateTime.AddHours(6);
    
    HtmlHelper<>TModel> newHtml = html;
    // How can I apply the new time to the newHtml model?
 
    return PropertyExtensions.PropertyFor(newHtml, expression);
}

#186373
Edited, Dec 18, 2017 20:23
Vote:
 

To get your above code to work you can try this:

public static MvcHtmlString PropertyForDateTime<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, DateTime>> expression)
{
    Func<TModel, DateTime> method = expression.Compile();
    DateTime value = method(html.ViewData.Model);
    DateTime displayValue = value.AddHours(6);

    return PropertyExtensions.PropertyRenderer.PropertyFor(html,
                (expression.Body as MemberExpression).Member.Name, null, null, expression, templateName =>
        {
            return new MvcHtmlString(displayValue.ToString());
        });
}


Another option would be to create your own date/time editor that doesn't normalize the dates to the user's local time zone.

See also this discussion for more information:

https://world.episerver.com/Modules/Forum/Pages/Thread.aspx?id=118042

#186400
Dec 19, 2017 11:27
Vote:
 

I must be tired today. Instead of above you can create a display template and save it as /Views/Shared/DisplayTemplates/DateTime.cshtml:

@model DateTime?

@if (!Model.HasValue)
{
    return;
}
 
@Model.Value.AddHours(6)


If you don't want it globally for all date properties you can give the display template another name and set UIHint on your property or explicitly set template name in PropertyFor helper.

@Html.PropertyFor(m => m.StartPublish, "MyTemplateName")
#186402
Edited, Dec 19, 2017 12:31
Vote:
 

Thank you Mattias.  The first solution you posted works.  I'll also explore those other options.

#186451
Dec 19, 2017 17:59
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.