24

I need to capture date and time both for my model property. In my model class I have the following

[Required]
[DataType(DataType.DateTime)]
public DateTime? CallBackDate { get; set; }

When I enter a valid date time (e.g. 28/05/2015 15:55) I keep getting this error The field CallBackDate must be a date.

I have seen similar question and tried various answers but nothing seems to get rid of this. I m using unobtrusive client side validation and I can't disable it.

The source of the input field has the following markup

<input autocomplete="off" class="jquery_datetimepicker form-control hasDatepicker" data-val="true" data-val-date="The field CallBackDate must be a date." data-val-required="The CallBackDate field is required." id="CallBackDate" name="CallBackDate" placeholder="Enter your CallBackDate" type="text" value="">

And jquery datetime picker has the following markup

$('.jquery_datetimepicker').datetimepicker({
    dateFormat: 'dd/mm/yy',
    minDate: 0,
    showWeeks: true,
    showStatus: true,
    highlightWeek: true,
    numberOfMonths: 1,
    showAnim: "scale",
    showOptions: {
        origin: ["top", "left"]
    },
    timeFormat: 'hh:mm tt'
});

Any ideas? thanks

rumi
  • 3,293
  • 12
  • 68
  • 109
  • possible duplicate of [Jquery Datepicker Chrome](http://stackoverflow.com/questions/5966244/jquery-datepicker-chrome) This looks to be a known issue with the client side validation. – Luke May 28 '15 at 15:07
  • @Coulton Its not definitely not a chrome or browser issue – rumi May 28 '15 at 15:13
  • Did you look at the answer? The solution on that question is not specific to chrome, the solution is to modify the behaviour of jquery.validate. You said that the error is being caused by the client side validation? – Luke May 28 '15 at 15:15
  • Yes I did look at the question and answers and its not related! – rumi May 28 '15 at 15:18
  • Is the error message raised on the server side or the client side? – Luke May 28 '15 at 15:20
  • Please see the updated question as I have added markup of the input field. `data-val-date="The field CallBackDate must be a date."` is added as an attribute probably from MVC annotations – rumi May 28 '15 at 15:24
  • Is the error message coming back from the server side validation or from the client side validation (ie javascript)? – Luke May 28 '15 at 15:29
  • `System.ComponentModel.DataAnnotations` are adding this validation attribute to the input field and then its checked at the client side. So the source of the issue lies on the server side – rumi May 28 '15 at 15:32
  • Yes, but in one case the validation error message will be displayed to the user before the data is posted to the action method (client side) and one will be raised against the model as the code runs through the action method (server side). Is it the one before the form is posted, or after? It is validated once on the client side (using javascript) and once on the server side. We need to isolate which side the validation is failing at. Thanks – Luke May 28 '15 at 15:34
  • yes it is occurring before the form is posted to the server. And if I remove the time part from the input field the date is accepted as valid – rumi May 28 '15 at 15:36
  • Ok, so it's a problem with jQuery Validate not validating the date correctly. – Luke May 28 '15 at 15:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/79034/discussion-between-coulton-and-learner). – Luke May 28 '15 at 15:38
  • Does the error message disappear if you change the date from the 28/05/2015 format to 05/28/2015, the US format? Or if you change the configuration of the jquery plugin to the american date format? – Luke May 28 '15 at 15:40
  • Changing the date format does not get rid of the error. The error is only removed if I remove the time part from the input – rumi May 28 '15 at 15:42
  • I wonder if it's down to the time format that you've specified: `timeFormat: 'hh:mm tt'`. Does it work without the `tt`? If I put a date in the format like `05/28/2015 15:55 00` in mine, it immediately raises the same error – Luke May 28 '15 at 15:43
  • No it does not make a difference. Thanks for all the help but I wonder why the question is closed – rumi May 28 '15 at 15:50
  • It's not closed :). Can I ask which jQuery plugin you are using for your date picker? – Luke May 28 '15 at 16:09
  • Its `http://trentrichardson.com/examples/timepicker/` and the jsfiddle is on http://jsfiddle.net/mccannf/2Kp56/1/ – rumi May 28 '15 at 16:11
  • 1
    You can modify validator as per [this answer](http://stackoverflow.com/questions/27285458/jquery-ui-datepicker-and-mvc-view-model-type-datetime/27286969#27286969) - but will depend on which datepicker you are using –  May 28 '15 at 21:44
  • Thanks for the comment Stephen. I will give that a try and let you know – rumi May 28 '15 at 21:51
  • @Learner, If the datepicker does not include a method that parses the date to your format, you can consider [this answer](http://stackoverflow.com/questions/30594128/error-in-date-validation-mvc/30609111#30609111) –  Jun 03 '15 at 01:05

14 Answers14

49

Client validation issues can occur because of MVC bug (even in MVC 5) in jquery.validate.unobtrusive.min.js which does not accept date/datetime format in any way. It is not caused by datepicker nor browsers. Unfortunately you have to solve it manually.

My finally working solution:

You have to include before:

@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")

You can install moment.js using:

Install-Package Moment.js

And then you can finally add fix for date format parser:

$(function () {
    $.validator.methods.date = function (value, element) {
        return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
    }
});
lukyer
  • 7,595
  • 3
  • 37
  • 31
  • Works perfectly thanks. I just needed to change the format to "DD/MM/YYYY". – ashilon Aug 15 '18 at 15:25
  • Hi, @lukyer, your code works well, but when I combine it with my MinAge attribute client validation, My MinAge validation becomes not working. Do you have an idea on how to make both validations work? I posted the details here: https://stackoverflow.com/questions/56629714/minimum-age-validation-with-dd-mm-yyyy-format-date-in-client-side-modelvalidatio – Wildan Muhlis Jun 17 '19 at 15:07
  • For DateTime in Dutch including the time I had to change the format a little: `D-M-YYYY HH:mm:ss`. I hope in the future asp.net mvc will make dealing with other locales more straightforward so we don't have to google for hours. – Wout Jan 07 '20 at 22:29
  • I am facing similar issue and i have posted the question as well: https://stackoverflow.com/questions/61114448/kentico-not-able-to-save-the-datetime-in-dd-mm-yyyy-format I have tried using the solution u have suggested, and when calling function to fix for date format parser, i added a debugger and the function(value, element) i.e. value and element parameters are showing as undefined. Can you please suggest for the same, is there something I am missing or do I need to pass some appropriate values for parameters? – Shubham Khandelwal Apr 23 '20 at 13:22
  • I changed date format to yyyy-mm-dd - fixes it and just a better date format. The world should just switch to this. – niico May 20 '21 at 16:12
8

I added the fix for date format parser, but I needed to set the format to 'L' so it could be work in all Locales:

$(function () {
$.validator.methods.date = function (value, element) {
    return this.optional(element) || moment(value, "L", true).isValid();
}
});
scae2201
  • 166
  • 2
  • 3
6

In the model for example:

    [Display(Name = "Insert Start Date")]
    [Required(ErrorMessage = "You must specify the date of the event!")]
    [DataType(DataType.DateTime, ErrorMessage = "Podaj prawidłową datę wydarzenia")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm}", ApplyFormatInEditMode = true)]
    public DateTime StartDate { get; set; }

    [Display(Name = "Insert End Date")]
    [Required(ErrorMessage = "You must specify the date of the event!")]
    [DataType(DataType.DateTime, ErrorMessage = "Podaj prawidłową datę wydarzenia")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm}", ApplyFormatInEditMode = true)]
    public DateTime EndDate { get; set; }

And View my example code:

<script>
$('#startDate').datetimepicker({
    onClose: function (dateText, inst) {
        var endDateTextBox = $('#endDate');
        if (endDateTextBox.val() != '') {
            var testStartDate = new Date(dateText);
            var testEndDate = new Date(endDateTextBox.val());
            if (testStartDate > testEndDate)
                endDateTextBox.val(dateText);
        }
        else {
            endDateTextBox.val(dateText);
        }
    }, dateFormat: 'yy-mm-dd',
    onSelect: function (selectedDateTime) {
        var start = $(this).datetimepicker('getDate');
        $('#endDate').datetimepicker('option', 'minDate', new Date(start.getTime()));
    }
}); ....

This caused positive effects: dateFormat: 'yy-mm-dd',

voltdev
  • 260
  • 1
  • 4
  • 9
  • [here](http://stackoverflow.com/questions/12633471/mvc4-datatype-date-editorfor-wont-display-date-value-in-chrome-fine-in-interne) is another **working solution** , hope helps. – Shaiju T Oct 05 '16 at 10:26
4
$(function () {
    $.validator.addMethod('date',
    function (value, element) {
        if (this.optional(element)) {
            return true;
        }
        var valid = true;
        try {
            $.datepicker.parseDate('dd/mm/yy', value);
        }
        catch (err) {
            valid = false;
        }
        return valid;
    });
    $(".datetype").datepicker({ dateFormat: 'dd/mm/yy' });
});

Put this code in a file datepicker.js and include this file in html

2

You need to make sure your application's Culture is properly set.

Example

The following example shows how cultures affect date parsing: https://dotnetfiddle.net/vXQTAZ

DateTime dateValue;
string dateString = "28/05/2015 15:55";

if (DateTime.TryParse(dateString, CultureInfo.CreateSpecificCulture("en-US"), DateTimeStyles.None, out dateValue))
{
    Console.WriteLine("Valid en-US date.");
}
else
{
    Console.WriteLine("Not a valid en-US date.");
}

if (DateTime.TryParse(dateString, CultureInfo.CreateSpecificCulture("fr-FR"), DateTimeStyles.None, out dateValue))
{
    Console.WriteLine("Valid fr-FR date.");
}
else
{
    Console.WriteLine("Not a valid fr-FR date.");
}

Output

Not a valid en-US date.

Valid fr-FR date.

Client Side Settings

You may also need to make sure that your client side validators are using properly cultures/globalization. If you are using jQuery validate plugin with MVC, see this extension to help modify that plugin to meet your needs: http://blog.icanmakethiswork.io/2012/09/globalize-and-jquery-validate.html

kspearrin
  • 10,238
  • 9
  • 53
  • 82
1
  1. Add following method in the additional-methods.js file and include this file in your project:

      $.validator.addMethod('date',
        function (value, element) {
            if (this.optional(element)) {
                return true;
            }
            var valid = true;
            try {
                $.datepicker.parseDate('dd/mm/yy', value);
            }
            catch (err) {
                valid = false;
            }
            return valid;
        });
  1. View must be like this:
       @Html.TextBoxFor(model => model.DOB, new { @class = "datetype", type ="text" })
       @Html.ValidationMessageFor(model => model.DOB)
     $(function () {
              $(".datetype").datepicker({ dateFormat: 'dd/mm/yy' }); 
      });

It works for me.

Kiran
  • 49
  • 6
0

I have to validate dd/mm/yyyy hh:ii and with help of @lukyer answer i have added DD/MM/YYYY HH:mm and it is working fine Hope this help !

Mustufa
  • 116
  • 4
0

I couln't solve it by the others answers. In my case, using TextBoxFor wasn't mandatory; I used TextBox instead.

Model

[Required(ErrorMessage = "Required")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime MyDate{get;set;}

View

@Html.TextBox("MyDate", DateTime.Now.ToString(), new {@type="datetime"})
fared
  • 161
  • 2
  • 12
0

localization or moment.js was not work for me while using datetimepicker. splitting hour and then checking is working. I am using format: 'dd.mm.yyyy hh:ii' for datetimepicker.

$.validator.methods.date = function (value, element) {
    var dateL = value.split(" ");
    var date = dateL[0].split(".");
    var hour = dateL.length > 1 ? dateL[1].split(":") : "";
    return this.optional(element) || !/Invalid|NaN/.test(dateL.length > 1 ? new Date(date[2], date[1], date[0],hour[0],hour[1]).toString() : new Date(date[2], date[1], date[0]).toString());
}
0

if you use JQuery unubtrosive validation you can add rules like behind and to change client-side validation message.

$('#inputName').rules('add',{
   messages:{
       date:'Invalid format date'
   }
})
Musa Aliji
  • 21
  • 2
0

In my case in my Model I had :

[DisplayFormat(DataFormatString = "{0:dd MMM yyyy}", ApplyFormatInEditMode = true)].

In my view in my script, I had:

    $(function () {
                $('.datepicker').datepicker({
                    changeMonth: true,
                    changeYear: true,
                    format: "dd MMM yyyy"
                });
        });

When I changed my script's format to format: dd M yyyy - it worked.

biruk1230
  • 3,042
  • 4
  • 16
  • 29
0

This works for me on both client and server side, I have moment.js installed too.

$("#datepicker").datepicker();
$('#datepicker').datepicker("option", "dateFormat", "dd/mm/yy");

$.validator.methods.date = function (value, element) {
    return this.optional(element) || moment(value, "DD/MM/YYYY", true).isValid();
}
Moji
  • 5,720
  • 2
  • 38
  • 39
0

In my case in _Layout.cshtml file I didn't have the jquery.js script. I just added the following line and it works:

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 06 '22 at 10:32
-1
  1. Install moment.js (Install-Package Moment.js)
  2. Open jquery.validate.js and find the method date: function (value, element)
  3. Replace the content for this:

    var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
    return this.optional(element) || (isChrome ? moment(value, 'L').isValid() : !/Invalid|NaN/.test(new Date(value)));
    
  4. Done
Bronks
  • 67
  • 1
  • 6