4

How to serialize the date time field with DateTimeKind option through ProtoBuf. When deserializing i want that date time field with DateTimeKind option.

I know we can achieve this by adding one additional property to convert the deserialized value in the UTC format.

For example, i have one date time field called UtcDateTime. it has the value in the UTC kind format. When serialize and deserialize this value i am getting the proper result, but it failed to retrieve date time kind option.

Here is my sample code:

[ProtoIgnore]                
public DateTime UtcDateTime { get; set; }

[ProtoMember(3)]           
public DateTime DateTimeValue           
{
    get { return UtcDateTime ; }
    set { UtcDateTime = DateTime.SpecifyKind(value, DateTimeKind.Utc); }   
} 

Now consider my case, my application has many date time fields like this. Instead of adding additional property in all places i need one generic solution to achieve this. If possible, please explain how to achieve this with sample C# logic. Thanks in advance.

Simply Ged
  • 8,250
  • 11
  • 32
  • 40
Umapathy S
  • 220
  • 2
  • 17

1 Answers1

6

Include this code to run before serializing or deserializing anything:

RuntimeTypeModel.Default.IncludeDateTimeKind = true;

Now your contract can be as simple as this (no need to double the properties):

[ProtoMember(3)]           
public DateTime DateTimeValue { get; set; }

And the value of DateTimeKind will be written and read automatically.

Compatibility concern

It worth noting that the original Protocol Buffers specification doesn't include DateTimeKind (it's specific to .NET) -- see protobuf-net does not deserialize DateTime.Kind correctly . Opt-in support of serializing DateTimeKind was added in protobuf-net v2.1.0.

If you exchange these messages with another system, it won't work unless the other end uses protobuf-net and sets IncludeDateTimeKind to true.

felix-b
  • 8,178
  • 1
  • 26
  • 36
  • Clarification: the "protocol buffers" specification doesn't touch this *at all*; protobuf-net added this at some point, but the recommendation would be to use the well-known types (using DataFormat.WellKnown; this uses the newer "Timestamp" layout); the well-known types *also* don't support any concept of "kind" – Marc Gravell Jul 03 '19 at 08:28