web-dev-qa-db-ja.com

Angularタイムゾーンに合わせたUI DatePicker

SQL Serverに日付として保存された日付があります。 SQLでクエリを実行すると、日付に2014年4月24日が表示されます。それは正しいです。日付はUTCでクライアント側に正しく引き渡されます。その日付を編集するには、Angular UIDatePicker。DatePickerはローカルタイムゾーンに基づいてその日付を調整しているため、常に1日オフになっています。

私はそれが起こっているのを見ることができます。日付ではなくDateTimeを編集している場合は、タイムゾーンを調整するのが正しいでしょう。ただし、この場合、私は日付だけを持っているので、タイムゾーンは気にせず、データベースにあった日付を編集したいだけです。

タイムゾーンに合わせて調整していることを確認できます。 WindowsマシンのタイムゾーンをUTCに変更すると、DatePickerに正しい日付が表示されます。

だから、質問は、DatePickerにタイムゾーン調整をオフにして、UTC形式で日付を管理するように指示して、SQL Datetimeの代わりにSQL Dateで動作するようにする方法はありますか?

46
Brian

私は非常に似た問題を少し前に持っていました:私はサーバー側にローカル日付を保存したかった(すなわち、yyyy-mm-ddだけでtimezome/time情報なし)Angular Bootstrap DatepickerはJavaScriptのDateオブジェクトを使用しますが、これは不可能でした(JSONのUTC日時文字列にシリアル化されます)。

このディレクティブで問題を解決しました: https://Gist.github.com/weberste/354a3f0a9ea58e0ea0de

基本的に、日付ピッカーで日付が選択されるたびに値を再フォーマットし(この値、yyyy-mm-dd形式の文字列はモデルに保存されます)、モデルにアクセスしてビューを作成するたびに、 Datepickerが適切に処理するように、Dateオブジェクトで再度ラップします。

42
weberste

ここにある解決策: https://github.com/angular-ui/bootstrap/issues/4837#issuecomment-203284205

タイムゾーンの問題は修正されました。

次を使用できます。

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

タイムゾーン計算なしで日付ピッカーを取得するには。

編集:このソリューションはバージョン2.x以降では機能しませんが、それまでは完全に問題ありませんでした。回避策が見つからず、バージョン1.3.3を使用しています。

編集2:セバスチャン・デプレが以下のコメントで指摘したように、これはバージョン2.3.1で修正されました。私はちょうどそれをテストし、それは素晴らしい作品です。

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

最初に、ブートストラップのローカライズされた日付ピッカーは愚かで役に立たないことを指摘したいと思います、誰もこのようなものを必要としません、あなたが本当に欲しいのは日付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」)です。

お役に立てれば!

1
valmarv

私にとっては、非常に古いバージョンのライブラリを使用し、オブジェクトexpiration_dateがdatepickerによって返されるため、回避策を見つけて、そのように微調整する必要がありました。

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

要求された日付を対応するUTC日付に設定しますが、それでもローカルタイムゾーン形式で表現されます。

私にとってはうまくいきました。それが誰かを助けることを願っています。

0

以下のディレクティブがあなたに役立つことを願っています

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
Pranav Labhe