javascript 不能正确地将 angular ui datepicker 日期转换为 UTC

Posted

技术标签:

【中文标题】javascript 不能正确地将 angular ui datepicker 日期转换为 UTC【英文标题】:javascript doesn't convert angular ui datepicker date to UTC correctly 【发布时间】:2015-01-26 03:40:17 【问题描述】:

我在我的项目(asp.net web api + angularjs)中使用了 angular ui datepicker。一切正常,但是当我尝试将日期保存到 Db 时,它并没有正确地将其转换为 UTC 格式并且子结构 1 天(实际上是几个小时,但它也会影响一天)。

例如,当我在日期选择器中选择 01/11/2014 时:

Angularjs object:
Sat Nov 01 2014 00:00:00 GMT+0200 (FLE Standard Time)

In request: 
2014-10-31T22:00:00.000Z

In asp.net api controller:
31-Oct-14 10:00:00 PM

日期选择器控制器:

app.controller('DatepickerCtrl', function ($scope) 
    $scope.today = function () 
        $scope.dt = new Date();
    ;
    $scope.today();
    $scope.clear = function () 
        $scope.dt = null;
    ;
    $scope.open = function ($event) 
        $event.preventDefault();
        $event.stopPropagation();

        $scope.opened = true;
    ;
    $scope.format = 'dd/MM/yyyy';
    $scope.dateOptions = 
        'starting-day': 1
    ;
);

hnml:

<div class="form-group inputGroupContainer" ng-controller="DatepickerCtrl">
                    <label for="date">Date of Birth</label>
                    <p class="input-group">
                        <input type="text" name="date1" ui-date="dateFormat: 'yy-mm-dd'" ui-date-format="yy-mm-dd" placeholder="DD/MM/YYYY" class="form-control" datepicker-popup="format" ng-model="user.Personal.BirthDate" max-date="currentDate" is-open="opened" close-text="Close" />
                        <span class="input-group-btn">
                            <button type="button"   class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
                        </span>
                    </p>
                </div>

但似乎有角度的日期选择器突出了正确的日期:

我尝试手动将日期转换为 UTC 格式,但也没有成功

   toUTCDate: function (d) 
            var date = new Date(d);
            var _utc = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());//, date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()
            return _utc;
        

我应该指定时区还是使用 Angular js 过滤器?

【问题讨论】:

【参考方案1】:

我遇到了完全相同的问题,解决方案是删除日期部分的时区部分。为了以更通用的方式解决问题,我编写了一个指令

csapp.directive("csDateToIso", 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
    ;
);

above 指令删除时区部分,只考虑 ISO 日期格式输入的日期部分。

我确实使用 moment.js 进行日期操作。但是您可以轻松地在上面转换为不使用 moment.js

编辑

像下面这样使用它

  <input ng-model='abc' cs-date-to-iso ui-datepicker>

【讨论】:

你是如何在 html 中使用的?? ?? 像魅力一样工作!我有一个小问题,它返回 undefined 值,但在我的 html 中添加 ng-model-options=" allowInvalid: true " 解决了它【参考方案2】:

只需添加 Entre 答案的咖啡脚本版本,它在 "angular": "~1.3.14", 中对我有用:

app.directive 'dateToIso', [ () ->

  restrict: 'A',
  require: 'ngModel'

  link: (scope, el, attrs, ngModel) ->
    if (angular.isUndefined(attrs.ngModel))
      console.log 'ngModel attribute missing for date-to-iso'
    else
      ngModel.$parsers.push (datePickerValue) ->
        return moment(datePickerValue).format("YYYY-MM-DD")
]

【讨论】:

【参考方案3】:

不要在 json 请求中发送 javascript 对象,javascript 在 JSON 中使用的对象的字符串表示中添加浏览器时区。您可以使用类似这样的方法将日期提取到没有时区的字符串中:

myApp.service('dateService', function()
    this.parse = function(date) 
        if(!date)
            return ""
        
        var day = (date.getDate() < 10 ? '0' : '') + date.getDate();
        var month = ((date.getMonth() + 1) < 10 ? '0' : '') + (date.getMonth() + 1);
        var hours = (date.getHours() < 10 ? '0' : '') + date.getHours();
        var minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
        var seconds = (date.getSeconds() < 10 ? '0' : '') + date.getSeconds();
        return date.getFullYear() + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds
    
);

然后在您的后端,您只需在您选择的时区中使用“yyyy-MM-dd HH:mm:ss”格式将字符串解析为日期对象。我不了解 .NET,但在 java 中你可以这样做:

def jsCalendarFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
jsCalendarFormat.setTimeZone(user.timezone)
Date dateObj = jsCalendarFormat.parse(date)

【讨论】:

以上是关于javascript 不能正确地将 angular ui datepicker 日期转换为 UTC的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将 Polyfills 添加到 SystemJS Angular 4 应用程序

如何正确地将值从 pyqt 返回到 JavaScript?

正确地将 Groovy 列表传递给 GSP 中的 Javascript 代码

Javascript:正确地将日期字符串转换为日期对象

如何正确地将字符数组写入文本文件

如何正确地将具有多个元素的新对象推送到数组中?