EditorFor to enter Time only, can't set it up for 24 hours format

Viewed 1886

I'm trying different things like different DataFormatString or even different controls to make it so it use 24 format but it keeps on AM/PM format, how to make it 24hs format?

EDIT: After more searching I realize this same code shows 24 hours format to some people, so I could reformulate to: What could be configured as AM/PM in my PC? I already changed the locale in web.config to a 24 hrs locale but the result is the same. My regional settings is also 24 hours time.

View:

<div class="col-md-2">
    Horario teórico Desde
    @Html.EditorFor(model => model.HorarioTeoricoDesde, new { htmlAttributes = new { @class = "form-control form-control-sm" } })
    @Html.ValidationMessageFor(model => model.HorarioTeoricoDesde, "", new { @class = "text-danger" })
</div>

ViewModel:

[Display(Name = "Horario Teorico Desde")]
[Required(ErrorMessage = "El Horario Teorico Desde es Requerido")]
[DataType(DataType.Time)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
public DateTime? HorarioTeoricoDesde { get; set; }

My Regional settings are 24 hs, spanish language. This is my web.config:

  <system.web>
    <globalization culture="es-AR" uiCulture="es-AR" />

This is how i see it:

This is how i see it:

Thanks!!

3 Answers

When you use DataType.Time the input is of type time.

Input type time is new in HTML5. Support of this type is still very poor. Even though you see the time in HH:MM AM/PM format (24 version (under development at this moment)), on the backend it still works in 24 hour format, you can try using some basic javascript to see that.

Example: Using bootstrap-timepicker.

ViewModel:-

public class Time24ViewModel
{
    [DataType(DataType.Time)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
    public DateTime? HorarioTeoricoDesde { get; set; }

    [Display(Name = "Horario Teorico Desde")]
    [Required(ErrorMessage = "El Horario Teorico Desde es Requerido")]
    public string HorarioTeoricoDesdeStr
    {
        get
        {
            return HorarioTeoricoDesde.HasValue ? HorarioTeoricoDesde.Value.ToString("HH:mm") : "";
        }
        set
        {
            if (!string.IsNullOrWhiteSpace(value))
            {
                var time = TimeSpan.Parse(value);
                HorarioTeoricoDesde = new DateTime(time.Ticks);

            }
        }
    }
}

Controller:-

public class TimeController : Controller
{
    // GET: Time
    public ActionResult Time24()
    {
        var model = new Time24ViewModel
        {
            HorarioTeoricoDesde = DateTime.Now
        };
        return View(model);
    }
    [HttpPost]
    public ActionResult Time24(Time24ViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }
        return View(model);
    }
}

View:-

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-timepicker/0.5.2/js/bootstrap-timepicker.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-timepicker/0.5.2/css/bootstrap-timepicker.css" rel="stylesheet" />

@using (Html.BeginForm("Time24", "Time", FormMethod.Post)) { 
<div class="col-md-2">
    Horario teórico Desde
    @Html.EditorFor(model => model.HorarioTeoricoDesdeStr, new { htmlAttributes = new { @class = "form-control form-control-sm" } })
    @Html.ValidationMessageFor(model => model.HorarioTeoricoDesdeStr, "", new { @class = "text-danger" })
</div>
<div class="col-md-2">
    <input type="submit" class="btn btn-dark" value="Submit"/>
</div>
}

<script>
    $('#HorarioTeoricoDesdeStr').timepicker({
        showMeridian: false
    });
</script>

(Tested)

When you use [DataType(DataType.Time)], the EditorFor method renders an input of type time.
According to the documentation, this input show the time in the format corresponding to the browser's locale.
Internally, the value of the input is still in the 24h format, is it purely about how the time is displayed.

For example:

<input type="time" value="23:13" class="text-box single-line" data-val="true" id="HorarioTeoricoDesde" name="HorarioTeoricoDesde">

Result in this in Firefox in English:
enter image description here

If you want to overwrite that, this question has some answers.


Old answer, works in some case but for the wrong reason:
If the type of the property is DateTime, you need to use this

[DataType(DataType.DateTime)]

instead of

[DataType(DataType.Time)]

In the other hand, if you only need the time part, you might consider using TimeSpan instead of DateTime but that depends on your project.

Changing the local won't(!) help -> The point is that it gives different output in different default locales (client side).
For example:

    en_SS: 12:00 AM
    fr_BL: 00:00
    ps_AF: 0:00
    es_CO: 12:00 a.m.

So you could try

@item.Date.ToString("0:HH:mm")

OR

To add a property to your model add this code:

public string ReturnDateForDisplay
{
    get
    {
       return this.ReturnDate.ToString("0:HH:mm");
    }
}

Then in your PartialView:

@Html.EditorFor(model => model.ReturnDateForDisplay)

For changing in create view all you have to do is apply the format you want in the html helper call, ie.

 @Html.TextBoxFor(m => m.YOUR_INPUT, "{0:HH:mm}")

EDIT
to get the result you want (showing plceholder and validation):

Use an overload of TextBoxFor() with an htmlAttributes argument. This argument should be an anonymous object with all attributes you wish to assign to the input.
For example, if you want to set the placeholder and class attributes:

@Html.TextBoxFor( model => model.HorarioTeoricoDesde, "{0:HH:mm}", new { 
       @class = "form-control datecontrol", type = "date" })

Other possible solutions: ASP.Net Forum
Additional Infos:
A preferred approach is to use a common format for all potential issues, and then the clients (your web UI) can format the value correctly before sending it to the back end / API. For dates and date times, use ISO 8601 format and have the accepted variable type be a string in the back end.

The time value would be listed as, e.g., 13:24 (HH:mm). Preferable for a few reasons:

  • The date format does not change between formats.
  • Strings do not have their value parts parsed incorrectly.
  • UTC / offset issues do not occur between the client and the server.
  • The ISO format string is sortable.
Related