javascript doesn't convert angular ui datepicker date to UTC correctly

試著忘記壹切 提交于 2019-12-17 18:51:43

问题


I'm using angular ui datepicker in my project(asp.net web api + angularjs). All works fine but when I'm trying to save date to Db it doesn't convert it to UTC format correctly and substructs 1 day(actually a few hours but it affects for a day too).

For example when I choose 01/11/2014 in the datepicker:

Angularjs object:
Sat Nov 01 2014 00:00:00 GMT+0200 (FLE Standard Time)

In request: 
2014-10-31T22:00:00.000Z

In asp.net api controller:
{31-Oct-14 10:00:00 PM}

Datepicker controller:

app.controller('DatepickerCtrl', function ($scope) {
    $scope.today = function () {
        $scope.dt = new Date();
    };
    $scope.today();
    $scope.clear = function () {
        $scope.dt = null;
    };
    $scope.open = function ($event) {
        $event.preventDefault();
        $event.stopPropagation();

        $scope.opened = true;
    };
    $scope.format = 'dd/MM/yyyy';
    $scope.dateOptions = {
        'starting-day': 1
    };
});

hnml:

<div class="form-group inputGroupContainer" ng-controller="DatepickerCtrl">
                    <label for="date">Date of Birth</label>
                    <p class="input-group">
                        <input type="text" name="date1" ui-date="{dateFormat: 'yy-mm-dd'}" ui-date-format="yy-mm-dd" placeholder="DD/MM/YYYY" class="form-control" datepicker-popup="{{format}}" ng-model="user.Personal.BirthDate" max-date="currentDate" is-open="opened" close-text="Close" />
                        <span class="input-group-btn">
                            <button type="button"   class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
                        </span>
                    </p>
                </div>

But seems like angular datepicker highlight the correct date:

I've tried to manually convert date to UTC format but unsuccessfully as well

   toUTCDate: function (d) {
            var date = new Date(d);
            var _utc = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());//, date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()
            return _utc;
        }

Should I specify timezone or use angular js filter?


回答1:


I have had the exact same problem, the solution was to remove the timezone component of the date part. To solve the problem in a more generic way I had written a directive

csapp.directive("csDateToIso", function () {

    var linkFunction = function (scope, element, attrs, ngModelCtrl) {

        ngModelCtrl.$parsers.push(function (datepickerValue) {
            return moment(datepickerValue).format("YYYY-MM-DD");
        });
    };

    return {
        restrict: "A",
        require: "ngModel",
        link: linkFunction
    };
});

above directive removes the timezone part and only considers the date part of the ISO date format input.

I do use moment.js for date manipulations. But you can easily convert above to not use moment.js

EDIT

use it like below

  <input ng-model='abc' cs-date-to-iso ui-datepicker>



回答2:


Just to add the coffeescript version of Entre's answer, which works for me in "angular": "~1.3.14",:

app.directive 'dateToIso', [ () ->

  restrict: 'A',
  require: 'ngModel'

  link: (scope, el, attrs, ngModel) ->
    if (angular.isUndefined(attrs.ngModel))
      console.log 'ngModel attribute missing for date-to-iso'
    else
      ngModel.$parsers.push (datePickerValue) ->
        return moment(datePickerValue).format("YYYY-MM-DD")
]



回答3:


Don't send the javascript object in the json request, javascript add the browsers timezone in the string representation of the object that is used in the JSON. You can use something like this to extract the date into an string without the timezone:

myApp.service('dateService', function(){
    this.parse = function(date) {
        if(!date){
            return ""
        }
        var day = (date.getDate() < 10 ? '0' : '') + date.getDate();
        var month = ((date.getMonth() + 1) < 10 ? '0' : '') + (date.getMonth() + 1);
        var hours = (date.getHours() < 10 ? '0' : '') + date.getHours();
        var minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
        var seconds = (date.getSeconds() < 10 ? '0' : '') + date.getSeconds();
        return date.getFullYear() + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds
    }
});

Then in your backend you only have to parse the string into a date object using the format "yyyy-MM-dd HH:mm:ss" in the timezone of your choosing. I don't know about .NET but in java you can do something like this:

def jsCalendarFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
jsCalendarFormat.setTimeZone(user.timezone)
Date dateObj = jsCalendarFormat.parse(date)


来源:https://stackoverflow.com/questions/27172394/javascript-doesnt-convert-angular-ui-datepicker-date-to-utc-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!