Angular UI DatePicker adjusting for timezone

前端 未结 6 591
忘了有多久
忘了有多久 2020-12-08 04:19

I have a date stored as a Date in SQL Server. The date shows 4/24/2014 when I query in SQL. That is correct. The date is correctly brought over to the client side in UTC. To

相关标签:
6条回答
  • 2020-12-08 04:42

    I had a very similar problem a while ago: I wanted to store local dates on the server side (i.e. just yyyy-mm-dd and no timezome/time information) but since the Angular Bootstrap Datepicker uses the JavaScript Date object this was not possible (it serializes to a UTC datetime string in the JSON as you found out yourself).

    I solved the problem with this directive: https://gist.github.com/weberste/354a3f0a9ea58e0ea0de

    Essentially, I'm reformatting the value whenever a date is selected on the datepicker (this value, a yyyy-mm-dd formatted string, will be stored on the model) and whenever the model is accessed to populate the view, I need to wrap it in a Date object again so datepicker handles it properly.

    0 讨论(0)
  • 2020-12-08 04:43

    First I'd like to point out that the bootstrap's localized date picker is stupid and useless, nobody needs something like this, all you really want is a date yyyy-MM-dd, I see no point in localizing a date when you don't need time.

    I don't try to bend the client side to fit the server's timezone, that's overkill and doesn't work. What I do instead is let the user work in it's timezone and format the date before sending it to the server like this:

    fields.date = dateFilter(trans.date, 'MM/dd/yy');
    

    This ensures that whatever the user sees in the date picker I receive on the server side. Crucial if you ask me. If you need to set min and max dates, again, just set them in the user's timezone like this:

    $scope.datepickerOptions.minDate = new Date(dateFilter(minDate, 'yyyy-MM-dd\'T\'00:00:00', serverTimezone));
    $scope.datepickerOptions.maxDate = new Date(dateFilter(maxDate, 'yyyy-MM-dd\'T\'00:00:00', serverTimezone));
    

    minDate and maxDate are server localized dates and the serverTimezone is the server's timezone offset ('+0500' for example).

    Hope this helps!

    0 讨论(0)
  • 2020-12-08 04:52

    Setting timezone to null worked like a charm for me. It just keeps the selected date as it is.

    ng-model-options="{timezone: null}"
    

    Note: Tested on all timezones & the uib version I'm using is 1.3.3

    0 讨论(0)
  • 2020-12-08 05:03

    Hope below directive is useful to you

    app.directive('datetimepickerNeutralTimezone', function () {
        return {
            restrict: 'A',
            priority: 1,
            require: 'ngModel',
            link: function (scope, element, attrs, ctrl) {
                ctrl.$formatters.push(function (value) {
                    if (typeof value === "undefined") {
                        var date = new Date();
                        //date = new Date(date.getTime() + (60000 * date.getTimezoneOffset()));
                        return date;
                    } else {
                        var date = new Date(Date.parse(value));
                        //date = new Date(date.getTime() + (60000 * date.getTimezoneOffset()));
                        return date;
                    }
                });
    
                ctrl.$parsers.push(function (value) {
                    var date = new Date(value.getTime() - (60000 * value.getTimezoneOffset()));
                    return date;
                });
            }
        };
    });
    
    app.directive('timepickerNeutralTimezone', function () {
        return {
            restrict: 'A',
            priority: 1,
            require: 'ngModel',
            link: function (scope, element, attrs, ctrl) {
                ctrl.$formatters.push(function (value) {
                    if (typeof value === "undefined") {
                    } else {
                        var date = new Date(Date.parse(value));
                        date = new Date(date.getTime() + (60000 * date.getTimezoneOffset()));
                        return date;
                    }
                });
    
                ctrl.$parsers.push(function (value) {
                    var date = new Date(value.getTime() - (60000 * value.getTimezoneOffset()));
                    return date;
                });
            }
        };
    });
    
    0 讨论(0)
  • 2020-12-08 05:07

    Solution found here: https://github.com/angular-ui/bootstrap/issues/4837#issuecomment-203284205

    The timezone issue is fixed.

    You can use:

    ng-model-options="{timezone: 'utc'}"

    To get a datepicker without timezone calculation.

    EDIT: This solution does not work since version 2.x, however it did perfectly fine until then. I couldn't find a workaround and still am using version 1.3.3.

    EDIT 2: As Sébastien Deprez pointed out in the comments below, this has been fixed in version 2.3.1. I just tested it and it works great.

    <input
     uib-datepicker-popup
     ng-model="$ctrl.myModel"
     ng-model-options="{timezone: 'utc'}">
    
    0 讨论(0)
  • 2020-12-08 05:07

    For me, because we use a very old version of the library, and given an object expiration_date returned by the datepicker, I had to find a workaround and tweaked it like that :

    expiration_date.setMinutes(-expiration_date.getTimezoneOffset());
    

    Which will set the requested date to its corresponding UTC date but still expressed in local timezone format.

    For me it worked well. Hope it can help someone.

    0 讨论(0)
提交回复
热议问题