Подтвердить что ты не робот

Angular Настройка пользовательского интерфейса DatePicker для часового пояса

У меня есть дата, хранящаяся как дата в SQL Server. Дата показывает 4/24/2014, когда я запрашиваю в SQL. Это верно. Дата корректно переносится на клиентскую сторону в UTC. Чтобы изменить эту дату, мы используем Angular UI DatePicker. DatePicker корректирует эту дату на основе моего локального часового пояса и поэтому всегда отключается на один день.

Я вижу, что это происходит. Если бы мы редактировали DateTime вместо Date, тогда было бы правильно настроить часовой пояс. Однако в этом случае у меня просто есть дата, поэтому мне не нужен часовой пояс, и я просто хочу отредактировать дату, как это было в базе данных.

Я могу проверить, что он настраивается для часовой пояс. Если я изменю часовой пояс на моей машине с Windows, чтобы быть UTC, то DatePicker показывает правильную дату.

Итак, вопрос в том, есть ли способ сообщить DatePicker отключить настройки часового пояса и просто управлять датами в формате UTC, чтобы он работал с SQL Date вместо SQL Datetime?

4b9b3361

Ответ 1

У меня была очень похожая проблема некоторое время назад: я хотел хранить локальные даты на стороне сервера (т.е. просто yyyy-mm-dd и не иметь информацию о времени/времени), но так как Angular Bootstrap Datepicker использует дату JavaScript объекту это было невозможно (он сериализуется в строку времени UTC UTC в JSON, как вы сами узнали).

Я решил проблему с этой директивой: https://gist.github.com/weberste/354a3f0a9ea58e0ea0de

По существу, я переформатирую значение всякий раз, когда дата выбирается на datepicker (это значение, yyyy-mm-dd форматированная строка, будет храниться в модели) и всякий раз, когда к модели обращаются, чтобы заполнить представление, Мне нужно снова обернуть его в объект Date, поэтому datepicker обрабатывает его правильно.

Ответ 2

Решение найдено здесь: https://github.com/angular-ui/bootstrap/issues/4837#issuecomment-203284205

Исправлена ​​проблема с часовым поясом.

Вы можете использовать:

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

Чтобы получить датупик без расчета часового пояса.

EDIT: это решение не работает с версии 2.x, однако до этого он отлично справился. Я не мог найти обходное решение и все еще использую версию 1.3.3.

EDIT 2: Как отметил Себастьян Депрез в комментариях ниже, это было исправлено в версии 2.3.1. Я просто протестировал его, и он отлично работает.

<input
 uib-datepicker-popup
 ng-model="$ctrl.myModel"
 ng-model-options="{timezone: 'utc'}">

Ответ 3

Сначала я хотел бы указать, что локализатор выбора начальной загрузки является глупым и бесполезным, никто не нуждается в этом, все, что вам действительно нужно, это дата yyyy-MM-dd, я не вижу смысла в локализации даты, когда вам не нужно время.

Я не пытаюсь согнуть клиентскую сторону, чтобы она соответствовала часовому поясу сервера, который перегружен и не работает. Вместо этого я хочу, чтобы пользователь работал в этом часовом поясе и форматировал дату перед отправкой на сервер следующим образом:

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

Это гарантирует, что независимо от того, что пользователь видит в наборе даты, я получаю на стороне сервера. Очень важно, если вы спросите меня. Если вам нужно установить минимальные и максимальные даты, просто установите их в часовом поясе пользователя следующим образом:

$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 и maxDate - это локализованные даты сервера, а serverTimezone - это смещение часового пояса сервера (например, "+0500" ).

Надеюсь, это поможет!

Ответ 4

Надежность ниже директивы полезна для вас

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;
            });
        }
    };
});

Ответ 5

Для меня, потому что мы используем очень старую версию библиотеки, и с учетом объекта expiration_date, возвращаемого DatePicker, мне пришлось найти обходной путь и настроить его так:

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

Который установит запрашиваемую дату в соответствии с соответствующей датой UTC, но все еще будет отображаться в формате локального часового пояса.

Для меня это сработало хорошо. Надеюсь, это может кому-то помочь.

Ответ 6

лучшим решением является использование библиотеки time.js, исправляющей всю ошибку между часовым поясом браузера и часовым поясом компонента