ServiceStack TypeSerializer:ISO8601和带有点作为TimeSeparator的文化

时间:2017-03-21 22:04:06

标签: c# datetime serialization servicestack iso8601

这是我的第一个问题,小心处理 在使用c#的.Net 4.5.2上,我在ServiceStack.Text 4.5.6序列化DateTime上发现了一个奇怪的行为:如果当前文化时间分隔符是点(。)并且序列化的DateTime是本地的或舍入的对于秒,即使使用DateHandler.ISO8601,序列化的结果也会将点作为时间分隔符。我做了一个简单的测试程序:

static void Main(string[] args)
{
    JsConfig.DateHandler = DateHandler.ISO8601;
    Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("bn-IN");

    var utcNow = DateTime.UtcNow;
    var utcRoundedToSecond = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, 
        utcNow.Hour, utcNow.Minute, utcNow.Second, DateTimeKind.Utc);
    var localNow = DateTime.Now;

    var utcNowSerialized = SerializeDateTime(utcNow);
    var utcRoundedToSecondSerialized = SerializeDateTime(utcRoundedToSecond);
    var localNowSerialized = SerializeDateTime(localNow);

    Console.WriteLine("Serialization tests:");
    Console.WriteLine("UTC \t\t\t{0}", utcNowSerialized);
    Console.WriteLine("UTC rounded to seconds \t{0}", utcRoundedToSecondSerialized);
    Console.WriteLine("Local \t\t\t{0}", localNowSerialized);
    Console.WriteLine();

    Console.WriteLine("Deserialization tests:");
    Console.WriteLine("UTC \t\t\t{0}", DeserializeDateTime(utcNowSerialized).ToString("o"));
    Console.WriteLine("UTC rounded to seconds \t{0}", DeserializeDateTime(utcRoundedToSecondSerialized).ToString("o"));
    Console.WriteLine("Local \t\t\t{0}", DeserializeDateTime(localNowSerialized).ToString("o"));

    Console.ReadKey();
}

private static string SerializeDateTime(DateTime dateTime)
{
    return TypeSerializer.SerializeToString(dateTime);
}
private static DateTime DeserializeDateTime(string str)
{
    return (DateTime)TypeSerializer.DeserializeFromString(str,typeof(DateTime));
}

输出:

Serialization tests:
UTC                     2017-03-21T21:24:41.1494902Z
UTC rounded to seconds  2017-03-21T21.24.41Z
Local                   2017-03-21T22.24.41.1494902+01:00

Deserialization tests:
UTC                     2017-03-21T22:24:41.1494902+01:00
UTC rounded to seconds  2017-03-21T22:24:41.0000000+01:00
Local                   2017-03-20T23:00:00.0000000+01:00

除了作为时间分隔符的点之外,反序列化后本地DateTime丢失了时间信息。在Windows上,如果将日期时间设置更改为使用HH.mm.ss和HH.mm而不是设置线程文化,则可以获得相同的结果。
这个可以吗?我错过了什么吗?我希望时间分隔符为:,或者至少使用相同的文化来保持一致。我假设JsConfig.DateHandler = DateHandler.ISO8601告诉TypeSerializer使用ISO8601,并且ISO8601不依赖于文化,并且不允许使用点作为时间分隔符。

1 个答案:

答案 0 :(得分:2)

序列化应该使用InvariantCulture,因此我已更新DateTimeSerializer.ToShortestXsdDateTimeString()以使用this commit中缺少的InvariantCulture(在评论中由@JeroenMostert强调)。

此更改可从v4.5.7 +现在available on MyGet获得。