c# - ServiceStack TypeSerializer : ISO8601 and culture with dot as TimeSeparator

标签 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 不依赖于文化并且不允许点作为时间分隔符。

最佳答案

序列化应该使用 InvariantCulture,所以我更新了 DateTimeSerializer.ToShortestXsdDateTimeString() 以在 this commit 中缺少它的地方使用 InvariantCulture(@JeroenMostert 在评论中突出显示)。 .

此更改适用于 v4.5.7+,现在为 available on MyGet .

关于c# - ServiceStack TypeSerializer : ISO8601 and culture with dot as TimeSeparator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42938991/

相关文章:

java - 在 Java 中处理大文件 - XML 或序列化文件,哪个更好?

c# - 如何使 Json.Net 跳过空集合的序列化

wcf - .NET 3.5中DateTime序列化的最佳做法

c# - 批量插入的 LINQ-to-SQL 性能问题

C# 释放 IntPtr 引用的内存

python - 将数据帧列转换为日期时间以进行重新映射

python - 查找天数差异(与当前日期比较)

c# - 如何使用c#在apache drill中显示来自sql server的数据

c# - log4net,单独的进程,单独的 RollingFileAppenders

javascript - 在 Javascript 中将 django 格式化为正确的格式?