我正在尝试使用KendoUI Scheduler窗口小部件(MVC助手)来过滤特定时区(例如,'Europe / Minsk')中的约会,这些约束设置在塔斯马尼亚的我自己的时区。 Scheduler小部件的时区设置为“Europe / Minsk”。我根据Telerik的代码库示例(http://www.telerik.com/support/code-library/kendoui-scheduler-server-filtering)启用了服务器过滤。但是,周视图的服务器调用向服务器提供了错误的日期和时间,在我自己的时区中提供相当于星期一午夜的UTC日期字符串,而不是配置的时区。
很容易理解为什么;看来我scheduler.view().startDate()
函数中的getAdditionalData()
返回的内容如下:Date {Mon Oct 19 2015 00:00:00 GMT+1100 (Tasmania Standard Time)}
,转换为“2015-10-18T13:00:00.000Z”,而不是本地等效项< em>相对于配置的时区。简而言之,在给定配置的时区的情况下,对scheduler.view().startDate()
的调用返回错误的日期。
我如何解决这个明显的问题?我没有看到任何其他方式知道调度程序显示的日期范围,似乎唯一的方法是检索它。
使用未更改的代码库示例可以重现该问题。只需尝试在一周的最后几个小时拖动约会,并在刷新后观察它完全消失。
为了快速参考,getAdditionalData函数如下:
function getAdditionalData() {
var scheduler = $("#scheduler").getKendoScheduler();
var result = {
start: scheduler.view().startDate().toISOString(),
end: scheduler.view().endDate().toISOString()
}
return result;
}
答案 0 :(得分:0)
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时间。
编辑:最后一天的事件未呈现的原因是因为我无意中更改了视图的endDate()。当然;日期在JavaScript中不是不可变的。
答案 1 :(得分:-2)
首先,我建议检查新的(并且非常有用)&#34;时区&#34;帮助文章解释了时区,JavaScript Date对象,Scheduler如何使用它们以及远程服务应如何处理日期:
最终修改:这是最后一次澄清后的解决方案,内部相关支持主题:
经过我们方面的一些额外测试并阅读您最后的回复后,我终于明白了您遇到的问题究竟是什么。该解决方案包括先前建议的服务器端日期处理(由于MVC DefaultModelBinder行为)和客户端代码的一些更改。请在下面查看 - 它将应用于GitHub中之前链接的演示(经过我们方面的一些额外测试)和StackOverflow:
获取正确范围开始/结束日期的客户端代码(包括视图的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;
}
用于在服务器端将日期转换为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();
}
}
}
服务器端的控制器:
public virtual JsonResult Read(FilterRange range)
{
return Json(taskService.GetRange(range.Start, range.End));
}
Here is a screencast 在两个不同的时区进行了测试。