Kendo UI Scheduler错误地转换时间,向后添加和减少小时数

时间:2015-01-29 23:42:53

标签: datetime kendo-ui timezone kendo-scheduler

我正在使用剑道调度程序,时区偏移似乎是增加小时数并减去与应该发生的相反方向的小时数。

当我将客户时区更改为更西部时区时,会在活动日期时间内添加小时数,当我将客户端浏览器更改为更东部时区时,会减去小时数。

因此太平洋时区的客户应该将开始时间视为上午10:00,而是显示为下午4:00。设置为大西洋时区的客户将开始时间视为中午12:00。

计划代码:

$("#scheduler").kendoScheduler({
    date: new Date(),
    height: 900,
    editable: false,
    views: [
        {
            type: "month",
            selected: true,
            eventHeight: 50,
            eventTemplate: $("#event-template-month").html(),
        },{
            type: "agenda",
            eventHeight: 50,
            eventTemplate: $("#event-template-sched").html(),
        }
    ],
    timezone: "America/New_York",
    dataSource: webinarSchedule,
});

事件信息保存在本地js文件的数组中,如下所示:

var webinarSchedule = [//Date are in utc -5:00
{
    title: "Part 1 <br/>The Golden Rule",
    shortName: "1) The Golden Rule ",
    presenter: "Bill Preston",
    description: "A great event",
    synopsis: "Learn stuff",
    seriesNote: "The first of a 4-part series.",
    registration: "https://attendee.gotowebinar.com/register/3782113333237861889",
    start: new Date("2015/1/24 1:00 PM"),
    end: new Date("2015/1/24 1:20 PM"),

},

4 个答案:

答案 0 :(得分:5)

是的,这似乎不正常。

我发现在处理JS日期(或一般计算中的日期)时保持理智的唯一方法是使用ISO格式序列化的UTC日期(通常,在服务器上存储UTC日期也是一个更好的主意)。所以,我建议使用适当的ISO字符串为源时区创建事件:

{
    title: "Part 1 <br/>The Golden Rule",
    shortName: "1) The Golden Rule ",
    presenter: "Bill Preston",
    description: "A great event",
    synopsis: "Learn stuff",
    seriesNote: "The first of a 4-part series.",
    registration: "https://attendee.gotowebinar.com/register/3782113333237861889",
    start: new Date(Date.parse("2015-02-11T13:00:00-05:00")), 
    end: new Date(Date.parse("2015-02-11T13:20:00-05:00")),
}

然后根本不设置调度程序时区选项(因此它使用本地)。如果您需要传递到服务器,您可能还想先使用toISOString处理日期。

答案 1 :(得分:2)

调度程序期望仅接收和发送UTC日期 - 这就是为什么你应该使用UTC时区以正确的格式加载它的数据(否则当从字符串创建日期时,将使用本地用户时区,这是JavaScript特定的行为):

start: new Date("2015-01-24T13:00:00.000Z"),
end: new Date("2015-01-24T13:20:00.000Z"),

此外,您可以将调度程序时区设置为“Etc / UTC” - 这样,上述日期将按原样显示,而无需在客户端进行转换:

$("#scheduler").kendoScheduler({
   date: new Date("2015/1/24"),
   timezone: "Etc/UTC",

以下是基于您的代码段的JSFiddle,显示了这一点:http://jsfiddle.net/loanburger/0s3Lcq17/

答案 2 :(得分:0)

该节目有点晚,但我目前正在评估Telerik的MVC组件,并且在使用调度程序时遇到了类似的问题。我处理它的方式是需要时区,然后服务器端我做了以下事情:

public SchedulerViewModel HandleTimezonesToUTC(SchedulerViewModel e)
{
    TimeZoneInfoHelper tziHelper = new TimeZoneInfoHelper();
    if (!string.IsNullOrEmpty(e.StartTimezone) && string.IsNullOrEmpty(e.EndTimezone))
    {
        TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(tziHelper.FindMSEquilivalent(e.StartTimezone));
        e.Start = DateTime.SpecifyKind(e.Start, DateTimeKind.Unspecified);
        e.End = DateTime.SpecifyKind(e.End, DateTimeKind.Unspecified);
        e.Start = TimeZoneInfo.ConvertTimeToUtc(e.Start, tzi);
        e.End = TimeZoneInfo.ConvertTimeToUtc(e.End, tzi);
    }
    if (!string.IsNullOrEmpty(e.StartTimezone) && !string.IsNullOrEmpty(e.EndTimezone))
    {
        TimeZoneInfo tziStart = TimeZoneInfo.FindSystemTimeZoneById(tziHelper.FindMSEquilivalent(e.StartTimezone));
        TimeZoneInfo tziEnd = TimeZoneInfo.FindSystemTimeZoneById(tziHelper.FindMSEquilivalent(e.EndTimezone));
        e.Start = TimeZoneInfo.ConvertTimeToUtc(e.Start, tziStart);
        e.End = TimeZoneInfo.ConvertTimeToUtc(e.End, tziEnd);
    }
    return e;
}

public SchedulerViewModel HandleTimezonesFromUTC(SchedulerViewModel e)
{
    TimeZoneInfoHelper tziHelper = new TimeZoneInfoHelper();
    if (!string.IsNullOrEmpty(e.StartTimezone) && string.IsNullOrEmpty(e.EndTimezone))
    {
        TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(tziHelper.FindMSEquilivalent(e.StartTimezone));
        e.Start = DateTime.SpecifyKind(e.Start, DateTimeKind.Utc);
        e.End = DateTime.SpecifyKind(e.End, DateTimeKind.Utc);
        e.Start = TimeZoneInfo.ConvertTimeFromUtc(e.Start, tzi);
        e.End = TimeZoneInfo.ConvertTimeFromUtc(e.End, tzi);
    }
    if (!string.IsNullOrEmpty(e.StartTimezone) && !string.IsNullOrEmpty(e.EndTimezone))
    {
        TimeZoneInfo tziStart = TimeZoneInfo.FindSystemTimeZoneById(tziHelper.FindMSEquilivalent(e.StartTimezone));
        TimeZoneInfo tziEnd = TimeZoneInfo.FindSystemTimeZoneById(tziHelper.FindMSEquilivalent(e.EndTimezone));
        e.Start = TimeZoneInfo.ConvertTimeFromUtc(e.Start, tziStart);
        e.End = TimeZoneInfo.ConvertTimeFromUtc(e.End, tziEnd);
    }
    return e;
}

通过这种方式,您可以删除任何意外的本地&gt; utc转换,并且正如其他海报之一所说,让浏览器为您调整回本地时间。

理论上你不应该需要fromUTC,但是当我测试时,日历并没有将它转换为当地时区。你可能只需要分配一个&#34; kind&#34;但我没有测试过。

不确定你在做什么,但希望它可以帮助你清理一些令人烦恼的摇摇欲坠的时间问题。

答案 3 :(得分:0)

我使用moment.js

解决了这个问题

Javascript:

new Date(moment.utc("INSERT DATE HERE").format())

这样我就消除了时区问题。我不会改变MVC控制器上的日期。