3

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!!

JCIsola
  • 110
  • 1
  • 11

3 Answers3

2

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)

Ashiquzzaman
  • 5,129
  • 3
  • 27
  • 38
0

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.

colinD
  • 1,641
  • 1
  • 20
  • 22
  • What i need to know is how to make the Annotation work for 24 hs, this is not working and using a culture that uses 24 hs is not helping either. DateTime shows date, that's not useful for me. Using TimeSpan I lose validations and ViewModel annotations. – JCIsola Mar 26 '20 at 21:18
  • In which language is your browser? When you use `DataType.Time` the input is of type 'time' and I believe the browser override the format you give to `DisplayFormat` and use the one of its culture. That would also explain why your code works for some people and not for other. – colinD Mar 26 '20 at 23:01
  • Yes i've been reading about the browser, but I tested in English Chrome in my PC and also Spanish Chrome in a development server, both display AM/PM format. Still maybe it could be something else in the browser's config. – JCIsola Mar 27 '20 at 03:22
  • That's strange, I tested with Chrome and if I set it to Spanish, the time show without the AM/PM, whereas with English it does. – colinD Mar 27 '20 at 07:58
0

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.
Codebreaker007
  • 2,911
  • 1
  • 10
  • 22
  • Changing the locale doesn't help. Also, reading the data from the field is not a problem, it shows perfectly in 24hs format in the HTML table and also in de Details view but not in the Create view. The problem is the 12 hrs format plus the AM / PM placeholder in the control and its validation on the Create view, that image in my post shows the control in the create view. – JCIsola Mar 29 '20 at 08:06
  • See my edit you should clarify your question though – Codebreaker007 Mar 29 '20 at 11:24
  • @Html.TextBoxFor(model => model.HorarioTeoricoDesde, "{0:HH:mm}") That is showing me an empty TextBox without validations nor placeholder for hours and minutes. Tryied with or without the datatype in the ViewModel. – JCIsola Mar 29 '20 at 20:50
  • Have you seen and tried my EDIT overloading TextBoxFor? – Codebreaker007 Mar 31 '20 at 09:51