我的 AngularJS 控制器和后端 entity framework 之间的日期时区丢失

Date timezone is lost between my AngularJS controller and Backend entity framework

我遇到 AngularJS 和 Entity Framework 之间缺少日期时区的问题。

这是我的 angular 代码示例:PLNKR

我从服务器端 (ASP.NET MVC5) 获取日期作为这样的字符串:"2015-02-17T00:00:00" 没有任何关于时区的信息。

为了将此字符串解析为日期并将其绑定到输入 [date],我为此使用了 angularjs 指令。

我的问题是:我的本地时区是+4,更改值并将其推回ngModel后,它被转换为UTC时间,所以日期部分将是-1 天回来。换句话说,如果我在日期输入中 select Feb 18, 2015,则 ngModel 值将是:2015-02-17T20:00:00.000Z。所以,当传递回服务器时,我在控制器中收到它是这样的:

{5/17/1988 8:00:00 PM}
    Date: {5/17/1988 12:00:00 AM}
    dateData: 5238841010427387904
    Day: 17
    DayOfWeek: Tuesday
    DayOfYear: 138
    Hour: 20
    InternalKind: 4611686018427387904
    InternalTicks: 627154992000000000
    Kind: Utc
    Millisecond: 0
    Minute: 0
    Month: 5
    Second: 0
    Ticks: 627154992000000000
    TimeOfDay: {20:00:00}
    Year: 1988

这个日期的种类是Utc。但是当我通过 Entity framework (v6) 将它传递给数据库时,它会在没有任何时区的情况下保存。所以,下次我加载它时,它将使用本地时区,因此与原始值相差 -4 小时,这是错误的。

entity framework 模型中的这个日期属性很简单,就像这样 public DateTime BirthDate { get; set; } 而在 DB (MSSQL) 中它是这样的 DateTime 类型: [BirthDate] DATETIME NOT NULL

我认为解决方案应该是:强制 Angular 仅使用本地时区,而我的应用程序将 运行 仅在本地使用,或者强制 entity framework 保存时区信息.

我更喜欢第一个选项,但是如何?

我通过将 angularJS 指令的 return 类型从 Date 对象更改为 yyyy-mm-dd 格式的字符串解决了这个问题。

之前:

(function() {
  function parseDateString(dateString) {
    if ('undefined' === typeof dateString || '' === dateString) {
      return null;
    }
    var parts = dateString.split('-');
    var year = parseInt(parts[0], 10);
    var month = parseInt(parts[1], 10);
    var day = parseInt(parts[2], 10);
    return new Date(year, (month - 1), day);
  }

  var mainApp = angular.module('mainApp', [])
    .directive('input', ['dateFilter',
      function(dateFilter) {
        return {
          restrict: 'E',
          require: '?ngModel',
          link: function(scope, element, attrs, ngModel) {
            if ('undefined' !== typeof attrs.type && 'date' === attrs.type && ngModel) {
              ngModel.$formatters = [ function(modelValue) { return dateFilter(modelValue, 'yyyy-MM-dd'); } ];
              ngModel.$parsers = [ function(viewValue) { return parseDateString(viewValue); } ];
            }
          }
        }
      }
    ]).controller("myController", function($scope) {
      $scope.testDate = "2015-02-17T00:00:00";
    });
}());

之后:

(function() {  
var mainApp = angular.module('mainApp', [])
  .directive('input', ['dateFilter',
    function(dateFilter) {
      return {
        restrict: 'E',
        require: '?ngModel',
        link: function(scope, element, attrs, ngModel) {
          if ('undefined' !== typeof attrs.type && 'date' === attrs.type && ngModel) {
            ngModel.$formatters = [
              function(modelValue) {
                return dateFilter(modelValue, 'yyyy-MM-dd');
              }
            ];
            ngModel.$parsers = [
              function(viewValue) {
                return dateFilter(modelValue, 'yyyy-MM-dd');
              }
            ];
          }
        }
      }
    }
  ]).controller("myController", function($scope) {
    $scope.testDate = "2015-02-17T00:00:00";
  });
}());