NancyFX不序列化带有尾随Z的日期以表示UTC/Zulu
题
我们将所有日期存储在数据库中作为UTC。
当它们从API返回给我们时,它们的格式如下
"createdDate":"2014-07-30T18:34:45"
但是正如你所看到的,日期没有尾随Z(这表明我们的角度应用程序是UTC/Zulu)。它应该是这样的
"createdDate":"2014-07-30T18:34:45Z"
我在我们的Bootstrapper中确实有以下设置
JsonSettings.ISO8601DateFormat = true;
在我的配置中,我可以确保有一个尾随 Z
为了UTC解析的目的?
解决方案
你使用的是什么版本的NancyFx?因为在v0.23.0或更高版本中,JsonSerializer代码已更改为使用"o"日期格式而不是"s"日期格式,这应该为您提供您正在查找的尾随Z。(但仅限于UTC日期时间。)
这是进行此更改的提交。 注意如何 DateTimeKind.Unspecified
日期被视为本地;如果您没有将DateTime对象显式创建为 DateTimeKind.Utc
.
下面是序列化DateTime值的NancyFx代码,因为它看起来像v0.23.0(在该提交之后)。从 https://github.com/NancyFx/Nancy/blob/v0.23.0/src/Nancy/Json/JsonSerializer.cs,第480-518行:
void WriteValue (StringBuilder output, DateTime value)
{
if (this.iso8601DateFormat)
{
if (value.Kind == DateTimeKind.Unspecified)
{
// To avoid confusion, treat "Unspecified" datetimes as Local -- just like the WCF datetime format does as well.
value = new DateTime(value.Ticks, DateTimeKind.Local);
}
StringBuilderExtensions.AppendCount(output, maxJsonLength, string.Concat("\"", value.ToString("o", CultureInfo.InvariantCulture), "\""));
}
else
{
DateTime time = value.ToUniversalTime();
string suffix = "";
if (value.Kind != DateTimeKind.Utc)
{
TimeSpan localTZOffset;
if (value >= time)
{
localTZOffset = value - time;
suffix = "+";
}
else
{
localTZOffset = time - value;
suffix = "-";
}
suffix += localTZOffset.ToString("hhmm");
}
if (time < MinimumJavaScriptDate)
time = MinimumJavaScriptDate;
long ticks = (time.Ticks - InitialJavaScriptDateTicks)/(long)10000;
StringBuilderExtensions.AppendCount(output, maxJsonLength, "\"\\/Date(" + ticks + suffix + ")\\/\"");
}
}
如您所见,请求ISO8601日期格式将为您提供2014-07-30T18:34:45格式,而不是自epoch以来的毫秒数,但如果正在序列化的值具有等于 DateTimeKind.Local
.
所以我有两个建议给你:如果您仍然使用v0.22或更早版本,请升级到NancyFx的v0.23(v0.22使用"s"日期格式,其中不包括时区信息,用于序列化日期时间值)。如果您正在序列化的DateTime对象没有显式设置为 DateTimeKind.Utc
, ,然后确保您指定 Utc
(由于默认为 Unspecified
, ,NancyFx视为等同于 Local
).