我有一个MVC应用程序,它以JSON格式从美国服务器发送日期值,并显示在智利的PC上。
服务器端在控制器中具有以下操作:
public async Task<ActionResult> GetFacturas(Models.DataTableAjaxPostModel model)
{
// Some other code in between
// ----
return Json(fecha); // fecha has the value of 2019-04-16 00:00:00
}
通过使用Chrome开发工具,我看到在JSON对象中收到的日期为1555383600000。
通过使用网站https://www.epochconverter.com/,我将该日期转换为易于阅读的格式,发现它是:
GMT: Tuesday, 16 April 2019 3:00:00
Your time zone: Monday, 15 April 2019 23:00:00 GMT-04:00
即使MVC控制器的日期为2019-04-16 00:00:00,似乎Json对其进行序列化时,它也使用-3时区转换为GMT,因此,最终客户端计算机收到了GMT日期,然后使用-4操作将日期转换回本地时间。
将操作系统配置为时区-4,并在web.config文件中以这种方式配置MVC应用程序:
<globalization culture="es-CL" uiCulture="es-CL" />
如何避免这个问题?
编辑:
“ fecha”变量是通过以下方式从数据库返回的DateTime对象:
var fecha = db.Entity.Select(f => f.DatetimeField).FirstOrDefault();
我当然简化了查询,但是事实是,“ fecha”在返回函数之前是一个DateTime对象,其值为2019-04-16 00:00:00。
致谢
Jaime
答案 0 :(得分:0)
我假设您的JSON中的值看起来像"/Date(1555383600000)/"
,它是较旧的JSON date format。使用这种格式,当.Kind
值的DateTime
属性为DateTimeKind.Local
或DateTimeKind.Unspecified
时,将应用服务器的本地时区。
即使存储在数据库中的值使用UTC,EF也无法得知,因此将其设置为未指定。您可以自己设置:
fetcha = DateTime.SpecifyKind(fetch, DateTimeKind.Utc);
现在,您会发现该值被序列化为"/Date(1555372800000)/"
。
当前版本的ASP.Net和Newtonsoft.Json改用ISO 8601格式。在不对代码进行任何更改的情况下,您的值将根据.Kind
属性进行序列化,如下所示:
DateTimeKind.Unspecified, as
“ 2019-04-16T00:00:00.0000000”`DateTimeKind.Utc
作为"2019-04-16T00:00:00.0000000Z"
DateTimeKind.Local
作为"2019-04-16T00:00:00.0000000-03:00"
(使用服务器的tz偏移量)您可以使用DateFormatHandling
setting在两种格式之间切换,但是我建议将其保留为默认的IsoDateFormat
。另请参见Serializing Dates in JSON。
客户端反序列化也是一个因素。如果您获得了一个时间戳(采用旧格式),则该时间戳将与UTC对齐。如果将字符串(采用新格式)交给您,则时间戳会受字符串中的偏移量的影响,如果没有提供偏移量,则受本地浏览器时区的影响。另外,JavaScript中的Date
对象具有许多只能 使用浏览器本地时区的功能。
考虑所有因素,要获得一个仅日期的值以进行端到端序列化而不受到某种时区的影响可能非常困难。您可以尝试上述方法,但如果确实只想保存,还原,显示和传输相同的仅日期值,那么您也可以考虑发送没有时间的字符串,如"2019-04-16"
:< / p>
return Json(fetch.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture"));