asp.net-mvcdatetimedata-bindingdatetime-formateditorfor

DateTime value binds hour incorrectly


I have an @HTML.EditorFor on an order form page where the user selects a time to pick up an order. I save the value in a Session and gets picked up by the Review page. The user can decide to edit where they are sent back to the order form with their previous values bound. All other values bind correctly except the pickup time, but only the hour. The minutes bind correctly, but for some reason the hour always displays as 3. I've watched the value while debugging; the value is always correct even after binding, but it always displays as 3.

My Model

[Required(ErrorMessage = "Pickup time is required")]
[DisplayName("Pickup time")]
[DisplayFormat(DataFormatString = "{0:h:mm tt}")]
[DataType(DataType.DateTime)]
public DateTime PickupTime { get; set; }

My View

@Html.EditorFor(model => model.Order.PickupTime, new { htmlAttributes = new 
{ @class = "form-control" } })

I'm creating a new Order object from the view model:

Order order = new Order() {
    PickupTime = ofvm.Order.PickupTime
};

I've tried different DataFormatStrings, using TempData and ViewBags instead of Sessions. The value is always correct in all those, but still no matter what the hour value is, it always displays as 3. Does anyone have any idea what is happening?


Solution

  • I found the solution. Still makes no sense to me as to why it wasn't binding correctly. But what fixed it was adding .TimeOfDay to the Linq expression in the EditorFor control, so instead of this:

    @Html.EditorFor(model => model.Order.PickupTime, new { htmlAttributes = new 
    { @class = "form-control" } }) // Always displayed '3' as the hour, no matter the value
    

    I did this:

    @Html.EditorFor(model => model.Order.PickupTime.TimeOfDay, new { 
    htmlAttributes = new { @class = "form-control" } }) // Displays correct hour value
    

    and the hour binds correctly now. I thought the DataFormatString attribute would be enough since the value is there, but for some reason it just didn't work. So from now on, whenever I need to bind a time value into an EditorFor control, I won't be using a format string.