2014-10-01 2 views
3

положение:Угловая планка Datepicker: Противоречивые метки время вернулось, UTC +0 против UTC +12 часов

  • Мы используем радиально-Strap-х datepicker и хотим вернуть UTC метку времени к серверу.
  • При выборе даты (без выбора времени) мы обнаружили, что некоторые компьютеры возвращают метку времени с 0:00, а некоторые - с 12:00.
  • Это был независимый от браузера браузер, но он отличался между компьютерами.

Проблема:

  • Некоторые компьютеры возвращают 0:00, некоторые 12:00.

Что я пробовал:

  • Во время отладки я обнаружил, что проблема возникла в строке 379 angular-strap/dist/modules/datepicker.js#L379, контроллер $ DATEVALUE возвращает «Сб мар 28, 1987 12:00:00 GMT. +0100 (W. Europe Standard Time) 'вместо' Сб. 28 марта 1987 00:00:00 GMT + 0100 (W. Europe Standard Time) ', значение, возвращаемое другими компьютерами.

Вопрос:

  • Как вернуть 0:00 время во всех ситуациях?

ответ

1

Я также столкнулся с такой же проблемой. То, что я сделал, написано директивой для преобразования даты utc date. проверьте образец кода. Это решает мою проблему.

(function (angular) { 
angular.module('myApp').directive('datePicker', ['$parse', 'dateFilter', function   ($parse, dateFilter) { 
    var inputDateFormat = 'dd/MM/yyyy'; 

    var utcDateGeneretor = function (dateString) { 
     if ('undefined' === typeof dateString || '' === dateString) { 
      return null; 
     } 

     var parts = dateString.split('/'); 
     if (3 !== parts.length) { 
      return null; 
     } 
     var year = parseInt(parts[2], 10); 
     var month = parseInt(parts[1], 10); 
     var day = parseInt(parts[0], 10); 
     if (year.toString().length < 4) { 
      return null; 
     } 

     if (month < 0 || year < 0 || day < 1) { 
      return null; 
     } 

     //Javascript month is zero based. thats why always reduce 1 form selected month. 
     return new Date(Date.UTC(year, (month - 1), day)); 
    }; 

    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function (scope, element, attrs, ctrls) { 

      var mindatecalvalue = parseInt(attrs["mindatecalvalue"], 10); 
      var maxdatecalvalue = parseInt(attrs["maxdatecalvalue"], 10); 
      var twoDigitCutoffSpecified = attrs["twoDigitCutoff"]; 
      var twoDigitYear1900cutoff = -1; //If a 2-digityear is less than this number it is treated as being 2000+, otherwise 1900+. 
      if (twoDigitCutoffSpecified) { 
       twoDigitYear1900cutoff = parseInt(attrs["twoDigitCutoff"], 10); 
       if (isNaN(twoDigitYear1900cutoff)) { 
        twoDigitYear1900cutoff = -1; 
       } else if (twoDigitYear1900cutoff <= 0) { 
        twoDigitYear1900cutoff += (new Date().getFullYear() - 2000); //A negative number is interpreted as a number of years before the current year. 
       } 
      } 

      var updateModel = function (dateText) { 

       var canonicalisedDateText = ensureFullYear(dateText, twoDigitYear1900cutoff); 

       // call $apply to bring stuff to angular model 
       scope.$apply(function() { 
        ctrls.$setViewValue(canonicalisedDateText); 
       }); 
       ctrls.$render(); 
      }; 

      var ensureFullYear = function (dateText, twoDigitYear1900cutoff) { 
       var findYearRegex = /(.+[^0-9])([0-9]+)\s*$/; 
       var dateParts = findYearRegex.exec(dateText); 
       if ((!dateParts) || (dateParts.length != 3)) { 
        return dateText; //can't find a year in this date. 
       } 
       var originalYearAsStr = dateParts[2]; 
       if (originalYearAsStr.length > 2) { 
        return dateText; //Not a 2-digit year. 
       } 
       var originalYear = parseInt(originalYearAsStr, 10); 
       var fullYear = 0; 
       if (originalYear <= twoDigitYear1900cutoff) { 
        fullYear = 2000 + originalYear; 
       } else { 
        fullYear = 1900 + originalYear; 
       } 
       var restOfDate = dateParts[1]; 
       return restOfDate + fullYear; 
      } 


      ctrls.$formatters.push(function (modelValue) { 
       return dateFilter(modelValue, inputDateFormat); 
      }); 

      ctrls.$parsers.push(function (dateString) { 
       return utcDateGeneretor(dateString); 
      }); 
     } 
    }; 
}]); 

})(angular); 
0

Вне исправления ошибки в вашей локальной копии AngularStrap вы можете создать директиву, чтобы обернуть директиву DatePicker. Я схватил плункер с углового ремешка и написал директиву декоратора, чтобы всегда возвращать 0:00 времени для всех ситуаций. Это приятно, потому что вы можете написать всю необходимую логику в директиве. Обратите внимание: эта директива создает часы на модели, а затем выполняет любые изменения, необходимые для обновления почты, и возвращает ее контроллеру вашего приложения через обратный вызов. Примечание. Я также переключился на moment.js для удобства использования.

Plunker

HTML:

<date-wrapper></date-wrapper> 

Директива:

app.directive('dateWrapper', function($compile) { 
    return { 
     restrict:'AE', 
     link:function(scope, element, attrs, ctrl) { 

      var html = '<input type="text" class="form-control" name="date" ng-model="selectedDate" bs-datepicker>'; 

      var e = $compile(html)(scope); 
      element.replaceWith(e); 

      scope.$watch('selectedDate', function(date) {   
       var updatedDate = moment.utc(date).hour(0).minute(0).second(0).format("YYYY-MM-DDTHH:mm:ss Z"); 

       scope.dateChanged(updatedDate); 
      }); 
     } 
    } 
}); 

приложения контроллера Пример:

// call back for updated date 
$scope.dateChanged = function(date) { 
    $scope.selectedZeroHourUtcDate = date; 
}; 
1

я тоже столкнулся аналогичная проблема повторного garding date-only selection ... Я решил это с помощью парсеров $ ng-model.

ngModelCtrl.$parsers.push(function (datepickerValue) { 
     return moment(datepickerValue).format("YYYY-MM-DD"); 
    }); 

Я использую moment.js для обработки даты.но выше решение может работать даже без moment.js, , как показано ниже. (Примечание: я гавань испытания ниже кода, так что вам, возможно, придется настроить его немного)

ngModelCtrl.$parsers.push(function (datepickerValue) { 
     //return new Date(datepickerValue).toISOString().substring(0,10); 
     return new Date(datepickerValue).format("YYYY-MM-DD"); 
    }); 

выше даст вам дату без метки времени. Но если ваше требование говорит, что вы всегда должны 0:00 в конце концов, это может также быть достигнуто очень легко ...

ngModelCtrl.$parsers.push(function (datepickerValue) { 
     return moment(datepickerValue).format("YYYY-MM-DD") + " 0:00"; 
    }); 

полная директива код, который я использовал для этого:

shared.directive("dateToIso", function() { 

    var linkFunction = function (scope, element, attrs, ngModelCtrl) { 

     ngModelCtrl.$parsers.push(function (datepickerValue) { 
      return moment(datepickerValue).format("YYYY-MM-DD"); 
     }); 
    }; 

    return { 
     restrict: "A", 
     require: "ngModel", 
     link: linkFunction 
    }; 
}); 

Я определил его как атрибут, чтобы вы могли использовать его с другими вашими директивами. вы можете использовать его, как показано ниже ...

  <input type="text" ng-model="myDate" name="date" bs-datepicker date-to-iso> 
+0

этот ответ помог вам? – harishr

Смежные вопросы