KendoUI Scheduler 服务器过滤正确的日期

KendoUI Scheduler server filtering with correct dates

问题

我正在尝试使用 KendoUI Scheduler 小部件(MVC 助手)来过滤特定时区(例如,'Europe/Minsk')中的约会,该计算机设置为我在塔斯马尼亚的时区。 Scheduler 小部件的时区设置为 'Europe/Minsk'。我根据 Telerik 的代码库示例 (http://www.telerik.com/support/code-library/kendoui-scheduler-server-filtering) 启用了服务器过滤。但是,周视图的服务器调用向服务器提供了错误的日期和时间,提供的 UTC 日期字符串相当于我自己时区的星期一午夜,而不是配置的时区。

很容易看出原因;看来我的 getAdditionalData() 函数 returns 中的 scheduler.view().startDate() 类似于:Date {Mon Oct 19 2015 00:00:00 GMT+1100 (Tasmania Standard Time)},它被转换为“2015-10-18T13:00:00.000Z”,而不是相对于配置的时区 的本地等效 。简而言之,根据配置的时区,调用 scheduler.view().startDate() 会返回错误的日期。

问题

我怎样才能解决这个明显的问题?我看不到任何其他了解调度程序显示的日期范围的方法,而且检索它的唯一方法似乎已损坏。

使用未更改的代码库示例可以重现该问题。只需尝试将约会拖到一周的最后几个小时,然后看着它在刷新后完全消失。

为了快速参考,getAdditionalData 函数如下:

function getAdditionalData() {
    var scheduler = $("#scheduler").getKendoScheduler();

    var result = {
        start: scheduler.view().startDate().toISOString(),
        end: scheduler.view().endDate().toISOString()
    }

    return result;
}

首先,我建议查看新的(非常有帮助的)"Timezones" 帮助文章,其中解释了时区、JavaScript 日期对象、调度程序如何与它们一起工作以及远程服务应该如何工作处理日期:

最终编辑:这是在此处和相关支持线程中进行最后澄清后的解决方案:

在我们这边进行了一些额外的测试并阅读了您最后的回复后,我终于明白了您遇到的问题到底是什么。该解决方案包括之前建议的服务器端日期处理(由于 MVC DefaultModelBinder 行为)和客户端代码的一些更改。请在下方查看 - 它将应用于之前在 GitHub 中链接的演示(经过我们这边的一些额外测试)和 Whosebug:

  1. 用于获取正确范围 start/end 日期(包括视图的 startTime/endTime)的客户端代码:

    function getAdditionalData() {
        var scheduler = $("#scheduler").data("kendoScheduler");
    
        var timezone = scheduler.options.timezone;
        var startDate = kendo.timezone.convert(scheduler.view().startDate(), timezone, "Etc/UTC");
        var endDate = kendo.timezone.convert(scheduler.view().endDate(), timezone, "Etc/UTC");
    
        //optionally add startTime / endTime of the view
        var startTime = kendo.date.getMilliseconds(scheduler.view().startTime());
        var endTime = kendo.date.getMilliseconds(scheduler.view().endTime());
        endTime = endTime == 0 ? kendo.date.MS_PER_DAY : endTime;
    
        var result = {
            Start: new Date(startDate.getTime() - (startDate.getTimezoneOffset() * kendo.date.MS_PER_MINUTE) + startTime),
            End: new Date(endDate.getTime() - (endDate.getTimezoneOffset() * kendo.date.MS_PER_MINUTE) + endTime)
        }
    
        return result;
    }
    
  2. Class 用于在服务器端将日期转换为 UTC:

    public class FilterRange
    {
        private DateTime start;
        public DateTime Start
        {
            get
            {
                return start;
            }
            set
            {
                start = value.ToUniversalTime();
            }
        }
    
        private DateTime end;
        public DateTime End
        {
            get
            {
                return end;
            }
            set
            {
                end = value.ToUniversalTime();
            }
        }
    }
    
  3. 服务器端控制器:

    public virtual JsonResult Read(FilterRange range)
    {
        return Json(taskService.GetRange(range.Start, range.End));
    }
    

Here is a screencast 上述解决方案在两个不同的时区进行了测试。

Vladimir 的回答提供了一种将日期范围转换为 UTC 的方法,但是调度程序上显示的日期范围不是 UTC,而是配置的时区。

使用神奇的 moment.js,我能够将其转换为正确的日期范围:

function getFilters() {
    var scheduler = $("#scheduler").getKendoScheduler();
    var start = moment.tz(getDateParts(scheduler.view().startDate()), scheduler.options.timezone);

    // Assuming the scheduler will never show part days, the end date needs an extra day to ensure events on the day are included.
    var actualEnd = new Date(scheduler.view().endDate());
    actualEnd.setDate(actualEnd.getDate() + 1);

    var end = moment.tz(getDateParts(actualEnd), scheduler.options.timezone);

    var result = {
        start: start.toISOString(),
        end: end.toISOString()
    }

    return result;
}

function getDateParts(date) {
    return [
        date.getFullYear(),
        date.getMonth(),
        date.getDate(),
        date.getHours(),
        date.getMinutes(),
        date.getSeconds()
    ];
}

这现在查询 Web 服务以查找可见日期范围内的所有事件,它可以正确执行。现在我只需要弄清楚为什么 Scheduler 小部件在最后一个日期不显示任何事件星期几视图,尽管这些在 Web 服务调用中以正确的 UTC 时间返回。

编辑: 最后一天的事件没有呈现的原因是我无意中更改了 view() 的 endDate。当然; JavaScript.

中的日期不是不可变的