using protobuf-net.dll
Version 1.0.0.280
When I deserialize a DateTime
(wrapped in an object), the date/time is ok but the DateTime.Kind
property is 'Unspecified'
Consider this test case to serialize/deserialize a DateTime.
[TestMethod]
public void TestDateTimeSerialization()
{
var obj = new DateTimeWrapper {Date = DateTime.UtcNow};
obj.Date = DateTime.SpecifyKind(obj.Date, DateTimeKind.Utc);
var serialized = obj.SerializeProto();
var deserialized = serialized.DeserializeProto<DateTimeWrapper>();
Assert.AreEqual(DateTimeKind.Utc, deserialized.Date.Kind);
}
public static byte[] SerializeProto<T>(this T item) where T : class
{
using (var ms = new MemoryStream())
{
Serializer.Serialize(ms, item);
return ms.ToArray();
}
}
public static T DeserializeProto<T>(this byte[] raw) where T : class, new()
{
using (var ms = new MemoryStream(raw))
{
return Serializer.Deserialize<T>(ms);
}
}
The Assert fails, the Kind == Unspecified
As a result of protobuf-net
not serializing this property (see below) one solution is to assume DateTimeKind
is equal to Utc when displaying dates on the client side (only where you know it should be UTC of course):
public static DateTime ToDisplayTime(this DateTime utcDateTime, TimeZoneInfo timezone)
{
if (utcDateTime.Kind != DateTimeKind.Utc)//may be Unspecified due to serialization
utcDateTime = DateTime.SpecifyKind(utcDateTime, DateTimeKind.Utc);
DateTime result = TimeZoneInfo.ConvertTime(utcDateTime, timezone);
return result;
}
This saves you having to assign to each DateTime
property on the receiving side.
protobuf.net has to maintain compatibility with the protobuf binary format, which is designed for the Java date/time datatypes. No Kind
field in Java -> No Kind
support in the protobuf binary format -> Kind
not transferred across the network. Or something along those lines.
As it turns out, protobuf.net encodes the Ticks
field (only), you'll find the code in BclHelpers.cs
.
But feel free to add another field in your protobuf message definition for this value.