how to handle date for posting purposes in the ser

2019-07-12 08:52发布

问题:

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.

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!

回答1:

  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")))