gpt4 book ai didi

c# - ASP.NET 4.6 MVC 如何返回包含具有正确时区的日期时间数据的 Json 结果?

转载 作者:行者123 更新时间:2023-12-05 06:25:25 27 4
gpt4 key购买 nike

我希望返回一个包含从数据库查询的日期时间的 Json 结果。在我的本地机器上测试没有任何问题,但是,在发布到生产服务器后,所有日期时间都提前 3 小时显示。我认为这是由于服务器位于另一个时区。

需要帮助来解决这个问题。

数据库中的数据(MS SQL):

StartDt: 2019-07-02 04:00:00.000

Controller.cs:

 [HttpGet]
public ActionResult GetAll()
{
CalendarModel calendarModel = new CalendarModel();

var calendarEvents = from cal in db.Calendar
orderby cal.created descending
select cal;


return Json(calendarEvents, JsonRequestBehavior.AllowGet);
}

从我的计算机获取的 Json 结果:

[
{
//some data
"startDt": "/Date(1562054400000)/",
//some data
},

上面的日期时间被解析为“2019-07-02T04:00:00.000-04:00”,这是正确的。

从生产服务器获取的 Json 结果(从同一数据库查询):

[
{
//some data
"startDt": "/Date(1562065200000)/",
//some data
},

这个日期时间是“2019-07-02T07:00:00.000-04:00”,这是错误的。

--------更新我的解决方案--------

感谢@TommasoBertoni的回答启发了我这个问题的关键原因是由于默认的Unspecified DateTime Kind但是变成了local 在 Json 序列化时。所以只需要将DateTime Kind设置为UTC即可解决,但注意前端解析DateTime也需要将其设置为UTC否则会被认为默认为 local

Controller.cs:

 [HttpGet]
public ActionResult GetAll()
{
CalendarModel calendarModel = new CalendarModel();

var calendarEvents = from cal in db.Calendar
orderby cal.created descending
select cal;
//Add this
foreach (var item in calendarEvents)
{
item.startDt = DateTime.SpecifyKind(item.startDt, DateTimeKind.Utc);
}

return Json(calendarEvents, JsonRequestBehavior.AllowGet);
}

.js(使用 moment.js 库)

//parse it as utc
moment.utc(startDt).format("YYYY-MM-DDTHH:mm:ss")

最佳答案

问题是 ASP.NET 使用 custom Microsoft JSON date format ,它将 DateTime 值编码为 /Date(ticks)/,其中 ticks 表示自纪元 (UTC) 以来的毫秒数。
因此,1989 年 11 月 29 日凌晨 4:55:30,在 UTC 中被编码为 /Date(628318530718)/(更多信息请参见 here)。

例子:

  • Microsoft JSON 日期格式:/Date(1563464520158)/
  • ISO 8601 格式:2019-07-18T15:42:02.4592008Z

如果 DateTime 有一个 Unspecified 类型,它将被假定为 Local 并且该值将被转换为 UTC 以获得自纪元以来的刻度。

这种 json 格式仍在 MVC 中使用,但不在 Web API 中:这意味着当您在 Controller 中并使用 Json 序列化结果时(...) 您将获得非 ISO 格式,但如果您在 ApiController 中,默认序列化程序是 Json.NET,它支持 ISO 8601 格式并获得'转换 DateTime 值。

因此,要修复此行为,要么切换到 Web API,要么如果您想继续使用 MVC Controller ,您可以查看这些问题的答案:

...或者您可以在 json 序列化之前强制 DateTime Kind 为 Utc,但我不建议这样做。


class TestRepo
{
public IEnumerable<DateTime> GetDates()
{
var now = DateTime.Now;

// Use DateTime instances with different Kind
// showing that it doesn't impact the serialization format.
var utc = DateTime.SpecifyKind(new DateTime(now.Ticks), DateTimeKind.Utc);
var local = DateTime.SpecifyKind(new DateTime(now.Ticks), DateTimeKind.Local);
var unspecified = DateTime.SpecifyKind(new DateTime(now.Ticks), DateTimeKind.Unspecified);

return new DateTime[] { utc, local, unspecified };
}
}
// MVC controller
public class MVCValuesController : Controller
{
public ActionResult Index()
{
IEnumerable<DateTime> dates = new TestRepo().GetDates();
return Json(dates, JsonRequestBehavior.AllowGet);
}
}

// json result:
[
"/Date(1563465361835)/", // <-- Utc
"/Date(1563458161835)/", // <-- Local
"/Date(1563458161835)/" // <-- Unspecified
]
// Web API controller
public class ValuesController : ApiController
{
public IEnumerable<DateTime> Get()
{
IEnumerable<DateTime> dates = new TestRepo().GetDates();
return dates;
}
}

// json result:
[
"2019-07-18T15:56:03.6401158Z", // <-- Utc
"2019-07-18T15:56:03.6401158+02:00", // <-- Local
"2019-07-18T15:56:03.6401158" // <-- Unspecified
]

关于c# - ASP.NET 4.6 MVC 如何返回包含具有正确时区的日期时间数据的 Json 结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57092326/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com