5

I'm working with ASP.NET MVC 4 and I'm getting a DateTime format issue.

In my view, I have 2 hidden elements which contains DateTime variables (from my ViewModel), a start date and an end date.

When I'm debugging, I can clearly see that my date format is correct (for instance: 17/06/2014 8:30:00). Then, when I'm trying to get these values to pass them to my post action, I got some weird DateTime formats: the day becomes month and the month becomes the day (still in my example, 17/06/2014 8:30:00 becomes 06/17/2014 8:30:00).

When I inspect the HTML code, I can clearly see that the change is done while the HTML code is generated:

<input data-val="true"  data-val-required="Le champ Date de début :  is required." id="StartDate" name="StartDate" type="hidden" value="06/17/2014 08:30:00" />

So, obviously, my ModelState is invalid in my controller and I can do nothing. Here's my View :

@using (Html.BeginForm("ConfirmAppointment", "Home", FormMethod.Post, new { avm = Model}))
    {
        @Html.HiddenFor(a => a.StartDate)
        @Html.HiddenFor(a => a.EndDate)

        //some code
    }

Any idea about how to get the correct DateTime in order to pass it to my controller?

EDIT : My ViewModel :

public class AppointmentViewModel
{
    [DataType(DataType.DateTime)]
    public DateTime StartDate { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime EndDate { get; set; }

    public string DisplayDate { get; set; }
}
4
  • Can you show the model class? Are you using data annotation? Commented Jun 17, 2014 at 6:13
  • Sure, I'm posting it right now. Commented Jun 17, 2014 at 6:14
  • This has nothing to do with annotation. The issue comes from having different localization settings on the server and the browser. Commented Jun 17, 2014 at 6:17
  • Input values coming from request are filled in by DefaultModelBinder and the date format for the DateTime variables will be decided on your CurrentUICulture of the application. Which is by default will be equivalent to your System Culture Commented Jun 17, 2014 at 6:17

4 Answers 4

4

The format for the dates will depend on the date and time settings on both your server and client machine.

If your server is set to use GMT but your client is set to use EST time zones, then your date formats will be different.

In the example you posted, the date format 06/17/2014 is MM/dd/yyyy - the month first. Typically, US based timezones, Eastern and Western Standard for instance, will use these (although I'm sure there are plenty more).

If you require a specific date format, then you can try setting that in your view, as follows:

@using (Html.BeginForm("ConfirmAppointment", "Home", FormMethod.Post, new { avm = Model}))
{
    <input type="hidden" id="StartDate" name="StartDate" value="@this.Model.StartDate.ToString("dd/MM/yyyy")" />
    <input type="hidden" id="EndDate" name="EndDate" value="@this.Model.EndDate.ToString("dd/MM/yyyy")" />

    //some code
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your answer and explanation. However, I've tried to do that and I'm getting this error : Models can only be used with expressions access field, ownership, index one-dimensional array or single-parameter custom indexer As I said, the problem is that the transformation is made in my HTML. The value of StartDate in my code is in a correct format.
@rughes Thanks for your update. A little last problem apparently : I'm not getting the correct values in my controller. Here's what I'm getting : 01/01/0001 00:00:00
@Traffy Good to hear. Don't forget to add any time based values to the code as well! The code above just includes the date.
@rhughes You're confusing the issue by equating format and culture. Culture defines conventional DateTime formats, which should be used consistently. DateTime formats don't change because of time zones.
2

You can simply convert it to the universe format yyyy-MM-dd, something like this:

@Html.Hidden("StartDate", @Model.StartDate.ToString("yyyy-MM-dd"))
@Html.Hidden("EndDate", @Model.EndDate.ToString("yyyy-MM-dd"))

Comments

0

Though it is answered, another option is to use a Datetimebinder to accept date time in all cultures you expect it to work.

public class DateTimeBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (value == null)
            return new object();
        string strRecdDate = value.AttemptedValue.ToString();

        DateTime curvalue;
        DateTime.TryParse(strRecdDate, CultureInfo.CurrentCulture, DateTimeStyles.None, out curvalue);

        CultureInfo ci = new CultureInfo("en-IN");
        if (curvalue == DateTime.MinValue)
        {
            DateTime.TryParse(strRecdDate, ci, DateTimeStyles.None, out curvalue);
        }

        return curvalue;
    }

1 Comment

I'd like to try your solution but can't make the code execute. Could you elaborate a bit more on how you'd make the code operate ? thx
0

when you pass the date from the view to controller first pass it as string then in your controller or in your function return it to date time then use it eg : date.ToString("yyyy-MM-dd") then return it to date time in your function "yyyy-MM-dd" this format by the way the valid format to pass date to SQL query

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.