ServiceStack TypeSerializer:ISO8601 和以点作为 TimeSeparator 的文化
ServiceStack TypeSerializer: ISO8601 and culture with dot as TimeSeparator
这是我的第一个问题,请慎重处理。
在使用 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# 的 .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.
此更改适用于 v4.5.7+,即现在 available on MyGet。