NancyFX没有用尾随Z序列化日期以表示UTC / Zulu

时间:2014-07-30 18:52:53

标签: angularjs datetime nancy

我们将所有日期存储在数据库中作为UTC。

当它们从API返回给我们时,它们采用以下格式

"createdDate":"2014-07-30T18:34:45"

但正如您所看到的,日期没有尾随Z(这表明我们的Angular应用程序是它的UTC / Zulu)。看起来应该是这样的

"createdDate":"2014-07-30T18:34:45Z"

我在Bootstrapper中有以下设置

JsonSettings.ISO8601DateFormat = true;

在我的配置中,我可以确保有一个尾随Z用于UTC解析吗?

1 个答案:

答案 0 :(得分:1)

您使用的是什么版本的NancyFx?因为在v0.23.0或更高版本中,JsonSerializer代码已更改为使用" o"日期格式而不是" s"日期格式,它应该为您提供您正在寻找的尾随Z. (但仅限于UTC日期时间。)

This is the commit that made this change.请注意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 + ")\\/\"");
        }
    }

正如您所看到的,请求ISO 8601日期格式将获得2014-07-30T18:34:45格式而不是自纪元以来的毫秒数,但如果序列化的值具有种类等于DateTimeKind.Local

所以我有两个建议:如果你仍然在v0.22或更早版本上升级到NancyFx的v0.23(v0.22使用了&#34; s&#34;日期格式,不包括时区信息,用于序列化DateTime值)。如果您序列化的DateTime对象未明确设置为DateTimeKind.Utc,请确保指定Utc(因为默认值为Unspecified,NancyFx将其视为Local相当于{{1}})。