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,因此看起来(在您的示例中)提前四个小时。
您可以考虑两种方法来解决这个问题:
您可以通过将 the timezone parameter 设置为 local
来告诉 FullCalendar 将所有时间戳调整为用户本地时间。这不需要更改后端,但意味着不同时区的用户将看到相对于他们自己的事件,而不是事件的本地时间。 (无论如何,这通常是需要的,因此请先考虑这一点。)
您可以将 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。
我正在将此 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,因此看起来(在您的示例中)提前四个小时。
您可以考虑两种方法来解决这个问题:
您可以通过将 the timezone parameter 设置为
local
来告诉 FullCalendar 将所有时间戳调整为用户本地时间。这不需要更改后端,但意味着不同时区的用户将看到相对于他们自己的事件,而不是事件的本地时间。 (无论如何,这通常是需要的,因此请先考虑这一点。)您可以将 MVC 代码中使用的序列化程序更改为使用 JSON.Net instead of the
JavaScriptSerializer
. By default, JSON.Net will use the standard ISO8601 format, and will preserve the offset of aDateTimeOffset
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。