2014-03-25 46 views
35

我有一個日期作爲日期存儲在SQL Server中。日期顯示4/24/2014當我在SQL中查詢。那是對的。日期被正確地帶到UTC的客戶端。要編輯該日期,我們使用的是Angular UI DatePicker。 DatePicker根據我的本地時區調整該日期,因此它總是關閉一天。針對時區的角度UI DatePicker調整

我可以看到它正在發生。如果我們編輯日期時間而不是日期,那麼爲時區調整是正確的。然而,在這種情況下,我只是有一個日期,所以我不在乎時區,我只是想編輯日期,因爲它在數據庫中。

我可以驗證它是否在調整時區。如果我將Windows機器上的時區更改爲UTC,則DatePicker會顯示正確的日期。

所以,問題是,有沒有辦法告訴DatePicker關閉時區調整,只管理UTC格式的日期,以便它可以使用SQL Date而不是SQL Datetime?

回答

34

前段時間我有一個非常類似的問題:我想在服務器端存儲本地日期(即只是yyyy-mm-dd,沒有timezome /時間信息),但由於Angular Bootstrap Datepicker使用JavaScript Date對象這是不可能的(它會在JSON中序列化爲UTC日期時間字符串,就像你自己發現的那樣)。

我解決此指令該問題:https://gist.github.com/weberste/354a3f0a9ea58e0ea0de

本質上講,我重新格式化每當日期在日期選擇器(此值,YYYY-MM-DD格式的字符串中選擇的值,將存儲在模型),並且每當訪問模型來填充視圖時,我需要再次將它包裝在Date對象中,以便datepicker正確處理它。

+0

它還挺作品之間的所有錯誤。但是,當您第一次使用來自服務器的yyyy-mm-dd字符串進行設置時,datepicker會調整時區。你如何防止它?有一張票在這裏打開:[問題2072](https://github.com/angular-ui/bootstrap/issues/2072) – jlareau

+1

好點,謝謝你指出 - 這是一個時區問題我相信UTC在後面。通過「撤銷」JavaScript日期引入的時區調整來更新Gist來解決此問題。 – weberste

+0

這個解決方案很好地工作,謝謝分享。 –

1

首先我想指出bootstrap的本地化日期選擇器是愚蠢的和無用的,沒有人需要這樣的東西,所有你真正想要的是一個日期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」例如)。

希望這會有所幫助!

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

解決方案在這裏找到:https://github.com/angular-ui/bootstrap/issues/4837#issuecomment-203284205

的時區問題是固定的。

您可以使用:

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

爲了得到一個datepicker沒有時區計算。

編輯:此解決方案從版本2.x不起作用,但它直到那時才完全正常。我無法找到解決方法,仍在使用1.3.3版本。編輯2:正如SébastienDeprez在下面的評論中指出的那樣,這已經在版本2.3.1中得到修復。我只是測試它,它的效果很好。

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

這是非常有幫助 - 謝謝! – Brendan

+0

我確認此解決方案有效,但不適用於較新版本。具體來說,它是版本> = 2.0.2和<= 2.3.0(至少)的bug。這很無聊。 –

+1

實際上,它會從2.3.1修復! https://github.com/angular-ui/bootstrap/issues/6235 –

-2

最好的解決方案是使用moment.js庫修復瀏覽器時區和組件時區