18 Şubat 2018 Pazar

Serialization of DateTime and DateTimeOffset in Json.NET

Deserializing string to DateTimeOffset

Json.NET uses the ISO 8601 format for representing the datetime strings, which is in the format of yyyy-MM-ddTHH:mm:ss.fffffffzzz. To dissect this format a little bit: 

yyyy: 4 digit years.
MM : 2 digit months. 
dd    : 2 digit days
"T"  : a literal that separates the "date" section from the "time" section.
HH  : 2 digit hours in the 24 hour format. 
mm  : 2 digit minutes
ss     : 2 digit seconds
fffffff: 7 digit fraction of seconds
zzz    :  offset from UTC. This can be in the format of -/+hh:mm (e.g. +02:00, 2 hours ahead of UTC) or it can be the literal "Z" which is the same thing as UTC (+00:00).

Examples would be:

"2000-01-01T12:34:56+02:00"
"2000-01-01T12:34+01:30"
"2000-01-01T12:34:56Z"
"2000-01-01 12:34:56"
"2000-01-01 12:34"
"2000-01-01"
"12:34:56+02:00"
"12:34:56Z"
"12:34:56"
"12:34"

As you can see, some parts of the datetime string can be omitted. and here are a few things to note about that:
  • When the date part is omitted altogether, Json.NET will then assume the date is today
  • When the time part is omitted, Json.NET will assume the time is 00:00:00 (midnight).
  • The literal "T" can be replaced with one or more spaces (generally a single space).
  • To state the obvious, the fraction of seconds can be omitted and will be assumed as zero.
  • When the UTC offset is omitted, it will be assumed as "local". That means Json.NET will use the current system timezone to calculate the UTC offset at the specified datetime. 

    Note that this is NOT necessarily same thing as the UTC offset today.  For example, deserializing "2000-01-01 11:22:33" will use the UTC offset of the local timezone on 2000-01-01 as opposed to today.  For Pacific Time Zone, the UTC offset on January 1st, 2000 was -08:00 hours. For the same time zone, the UTC offset on July 1st, 2000 was -07:00 hours. 

Deserializing string to DateTime

Almost all of above is also correct when deserializing a string to DateTme. However, since DateTime cannot express the UTC offset, the offset is pretty much ignored, except for setting the DateTime.Kind property:
  • If the offset is included in the form of +/-hh:mm, the DateTime.Kind is set to "Local":
    "2000-07-01T12:34+03:00" -->  DateTimeKind.Local
  • If the offset is specified as UTC using the literal "Z", the DateTime.Kind is set to "Utc":
    "2000-07-01T12:34Z"  --> DateTimeKind.Utc
  • If the offset is omitted, the DateTime.Kind is set to "Unspecified":
    "2000-07-01T12:34"  --> DateTimeKind.Unspecified

Serializing DateTimeOffset to string

This is pretty straightforward. When serializing a DateTimeOffset, it always produces a string in the ISO 8601 format we mentioned above.  Maybe the only thing to note here, the fraction of seconds will not be in the string, unless it's greater than zero. 

Serializing DateTime to string

Same as DateTimeOffset, serializing a DateTime will produce a string in the ISO 8601 format above. However, the presentation of the offset depends on the DateTime.Kind property:
  • DateTimeKind.Local will produce a string with the offset set to the local timezone's UTC offset at the specified time. e.g. new DateTime(2000,1,1,0,0,0,DateTimeKind.Local) will be serialized with the UTC offset of the local timezone on 2000-01-01.
  • DateTimeKind.Utc will produce a string with the literal "Z" as the offset.
  • DateTimeKind.Unspecified will produce a string with no offset specified. 


Hiç yorum yok:

Yorum Gönder