FullCalendar 中的 DateTimeOffset 使用 ASP.NET MVC

DateTimeOffset in FullCalendar using ASP.NET MVC

我正在将此 DateTimeOffset 2016-08-01 09:30:00.0000000 -04:00 从我的 SQL 服务器数据库传递到 FullCalendar。事件似乎正在呈现,但它们总是提前 4 小时。我想指出的是,当我改用 datetime2 时,它正在做完全相同的事情。我检查了 SQL 服务器,它显示了正确的当前时间,所以我不确定问题出在哪里。

这是我的 FullCalendar 实现:

<script type="text/javascript">
    $(document).ready(function ()
    {
        $('#calendar').fullCalendar(
        {
            header:
            {
                left: 'prev,next today',
                center: 'title',
                right: 'month,agendaWeek,agendaDay'
            },
            editable: false,
            events: "/home/loadevents/"

        })
    });
</script>

视图模型:

public class CalendarEventsViewModel
{
    //Properties have to conform to the following API standards
    //or the FullCalendar.js library will reject all incoming data.
    //http://fullcalendar.io/docs/event_data/Event_Object/

    public int id { get; set; }
    public string title { get; set; }
    public DateTimeOffset start { get; set; }
    public DateTimeOffset end { get; set; }
}

AcctionResult/Linq:

public ActionResult LoadEvents (DateTime start, DateTime end)
{

    IEnumerable<CalendarEventsViewModel> model =
    db.CalendarEvents
    .Select(r => new CalendarEventsViewModel
    {
        id = r.EventID,
        title = r.EventName,
        start = r.EventScheduleDateTime,
        end = r.EventScheduleDateTime,
    });


    return Json(model, JsonRequestBehavior.AllowGet);
}

编辑:

通过断点仔细查看后,我注意到不是将 2016-08-01 09:30:00.0000000 -04:00 推送到 FullCalendar,而是推送 8/1/2016 09:30:00 AM,但它仍然显示为比我的本地时间提前四个小时。我不确定在我的 linq 语句中偏移量是否从数据库中丢失,即使我在数据库和视图模型 属性 中都使用了 datetimeoffset。我还在上面添加了更多代码。

编辑 2:

看来我错了,它正在发送 {8/1/2016 9:30:00 AM -05:00} 所以我不确定问题是什么。我的猜测是这可能不符合 FullCalendar 要求?

编辑 3:

在我的数据库中,我存储了 2016-08-01 09:30:00.0000000 -04:00。根据调试,当它到达 linq 查询时,它变成 8/1/2016 9:30:00 AM -04:00 。当 date/event 显示在 FullCalendar.js 时,它显示为比 1:30pm 晚了四个小时。我一定是对偏移有误解,但我不知道是什么。

因为您正在使用 MVC 的 JsonResult(通过调用控制器的 Json 方法返回),JSON 序列化由 JavaScriptSerializer class。不幸的是,这个特定的序列化程序不能很好地处理 DateTimeOffset 值。它将它们标准化为 UTC,然后在 an antiquated format.

中呈现它们

虽然 moment.js 确实可以读取该格式(因此 FullCalendar 也可以),但规范化过程意味着所有时间都将显示为 UTC,因此看起来(在您的示例中)提前四个小时。

您可以考虑两种方法来解决这个问题:

  1. 您可以通过将 the timezone parameter 设置为 local 来告诉 FullCalendar 将所有时间戳调整为用户本地时间。这不需要更改后端,但意味着不同时区的用户将看到相对于他们自己的事件,而不是事件的本地时间。 (无论如何,这通常是需要的,因此请先考虑这一点。)

  2. 您可以将 MVC 代码中使用的序列化程序更改为使用 JSON.Net instead of the JavaScriptSerializer. By default, JSON.Net will use the standard ISO8601 format, and will preserve the offset of a DateTimeOffset value. If you want to do this globally throughout your project, see this approach,但您也可以简单地将 LoadEvents 方法的最后一行更改为:

    string json = JsonConvert.SerializeObject(model);
    return Content(json, "application/json");
    

    另外值得一提的是 ASP.Net WebAPI 没有这个问题,因为它已经默认使用 JSON.Net。