2

I have this value from ASP.NET MVC /Date(1446393600000)/ which its value in SQL Database is '2015-11-02' which is a date (date only) and to manipulate it as javascript object, I used moment.js, so when used as moment('/Date(1446393600000)/') I got this result "2015-11-01T16:00:00.000Z"

And so this code:

The bindingHandler can be found here

ko.bindingHandlers.datepicker = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    var options = allBindingsAccessor().datepickerOptions || {},
        $el = $(element);

    //initialize datepicker with some optional options
    $el.datepicker(options);

    //handle the field changing
    ko.utils.registerEventHandler(element, "change", function() {
      var observable = valueAccessor();
      observable(moment($el.datepicker("getDate"))); // I added moment function here
    });

    //handle disposal (if KO removes by the template binding)
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
      $el.datepicker("destroy");
    });

  }
  /*,
    update: function(element, valueAccessor) {
      var value = ko.utils.unwrapObservable(valueAccessor()),
        $el = $(element),
        current = $el.datepicker("getDate");

      if (value - current !== 0) {
        $el.datepicker("setDate", value);
      }
    }*/
};
  
var vm = {
  sampleDate: ko.observable(moment('/Date(1446393600000)/')), // I added moment function here
  originalValue: '/Date(1446393600000)/', // For reference only
  FromSqlDb: '2015-11-02' // For reference only
};

vm.formattedDate = ko.pureComputed(function() {
  return this.sampleDate() ? 
    this.sampleDate().format("ddd, DD MMM YYYY") :
  '';
}, vm);
 

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<input type="text" data-bind="datepicker: sampleDate" /> <br />
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

As you can see, the value 2015-11-02 is now converted to UTC "2015-11-01T16:00:00.000Z" when I used moment() on it. Which is I don't want, since I want to retain what I have got from the db

So my question is:

  1. Does momentjs always convert your date to its utc?
  2. When I try to post the sampleDateI got this error. enter image description here

My temporary solution is to post the computed variable. (formattedDate and it works)

Please help me understand why the error occur. Any help would be much appreciated thanks!

Community
  • 1
  • 1
Boy Pasmo
  • 8,021
  • 13
  • 42
  • 67

1 Answers1

2
  1. The date is what you chose. Use moment's toDate and you'll get a js Date object which has the expected value. What you see is the UTC representation, i.e. the same hour translated to the Z zone (meridian 0, or Greenwrich meridian).

  2. Accordint to the OP comment, the date is posted by using .toISOString(). In this case, if you're in a time zone other than Z (Greenwich meridian), the date will refer to the previous date. For example the date 2015-04-20 GMT+1, will be formatted as 2015-04-19T23:00:00.000Z, and the server will clip the time and time zone info, so it will get one day before the desired day.

To avoid the problem in 2. we can instruct moment to parse the date as if it was an UTC date, like this: moment.utc('datestring'). For example, doing moment.utc('2015-03-11') will create the date 2015-03-11T00:00:00.000Z, so the covnersion to ISO string will give the desired date. In this instance, you have to change this line of code:

observable(moment($el.datepicker("getDate")))

to

observable(moment.utc($el.datepicker("getDate")))
JotaBe
  • 38,030
  • 8
  • 98
  • 117
  • for #1, am I right, that if the date has `Z` at the end is represented as UTC based on ISO-8601 format? #2 I tried using `toDate` but ended posting the minimum value of the date, instead i used `toISOString`. What do you think? – Boy Pasmo Nov 03 '15 at 13:46
  • If you use `toISOString`, the date is represented in time zone Z. And, unless you make a custom binder ASP.NET MVC simplty takes the date without taking into account the time zone. For any country in the east of that time zone (western Europe, except Portugal and UK) will get the date of the date before. You could try to correct this by using moment `.utcOffset` before posting. But this would lead to problems if you started to use the date and time parts. – JotaBe Nov 03 '15 at 13:55
  • Yes. But I won't be needing the time portion since I only need to store `date` and date only. Im round tripping a calendar date. What I retrieve from the database will be the same value of what it will appear on the page. No converting. What options do I have? Since `toDate()` will give me minimum date value. Will `toISOString` do? – Boy Pasmo Nov 03 '15 at 14:01
  • I've updated my answer to provide you an easier solution – JotaBe Nov 03 '15 at 14:53