我正在使用 Angular 和全日历。我有(意外的)时区问题,但似乎无法正确解决。

如果在周 View 中单击08.00小时,则打开一个模态并显示时间,我看到09.00小时。

timezone: "Europe/Brussels",
ignoreTimezone: false,

这是(atm)+0100时区,夏季是+0200时区

点击事件:
dayClick: function (date, jsEvent, view) {

    $scope.newEventDate = date;

    var modalInstance = $modal.open({
        templateUrl: 'newRosterEvent',
        controller: 'NewEventModalController',
        backdrop: "true",
        resolve: {
            event: function () {
                       return $scope.newEventDate;
                   },
            stage: function () {
                       return $scope.stage;
                   }
            }
       });

要显示时间:
stagewebApp.controller('NewEventModalController', ["$scope", "$modalInstance","$filter", "event", "stage", function ($scope, $modalInstance, $filter,event, stage) {

    $scope.stage = stage;

    $scope.day = new Date($filter('date')(event._d, "yyyy-MM-dd"));

    $scope.start = event.toDate();

    ....more code....
}

在这种情况下,$ scope.start显示单击的时间+1

因此,似乎fullcalendar花费了我单击的时间并将其转换为所选的时区,但是我希望它可以将单击的时间解释为位于我选择的时区中。

显然我正在解决这个错误,那么正确的方法是什么? ($scope.start应该显示我单击的时间(最好在我的时区))。之后,我将其发送到存储为UTC的服务器。

最佳答案

当前版本的FullCalendar广泛使用moment.js。您正在描述的问题是由于moment对象使用不当引起的。具体来说:

$scope.start = event.toDate();

调用toDate时,您将返回一个常规的JavaScript Date对象-该对象将基于相同的UTC时刻,但将始终采用代码运行时区的行为。您有几种选择:
  • 您可以将其保留为moment对象:
    $scope.start = event;
    
  • 您可以将其格式化为保留时区偏移量的ISO字符串:
    $scope.start = event.format(); // ex: '2015-03-04T08:00:00+01:00'
    

  • 无论使用哪种选项,您都需要遵循$scope.start的用法,以期望使用moment或字符串,而不是Date

    另外,在此代码中:
    $scope.day = new Date($filter('date')(event._d, "yyyy-MM-dd"));
    

    永远不要直接访问_d属性,因为这可能会产生意想不到的副作用。考虑下划线是指“内部”。另外,由于矩对象具有格式化功能,因此您在这里不需要Angular的日期过滤器。相反,只需执行以下操作:
    $scope.day = event.format("YYYY-MM-DD");
    

    10-05 20:47
    查看更多