Azure time zone and javascriptserializer object

2019-07-04 09:43发布

问题:

I have a predictions-based app that's up on Windows Azure ( http://ipredikt.com ). From what I can tell Azure's clock is synchronized to the GMT time zone. Here is a problem that I am encountering:

Let's say I have a DB field called CreateDate of type DateTime and I set its value to June 10, 2011, 12:30am. when a new prediction is created. If I peek inside the db table the date is correctly set. I don't touch or change this value in any way. However, when I read the value with our API, serialize it and send it to the client I get a date with the value of June 09, 2011, 5:30 pm. (The API dll also lives on the cloud and probably is collocated with the DB.)

My client browser is running in the PST (pacific time zone) and it seems that the 7 hour difference is due to the difference between PST and GMT. The API code used to serialize the value is similar to this:

System.Web.Script.Serialization.JavaScriptSerializer serializer = new JavaScriptSerializer();

return serializer.Serialize(dataObject);

Is this a bug in JavaScriptSerializer object or is there a trick to fix this delta? Basically, I don't want the .NET framework to interfere with this value in any way, I just want the DB field to just get returned as is.

回答1:

When you pass DateTime object to Azure its Kind equals to Local.
(June 10, 2011, 12:30am -7)

However, when you save it to the database the region information is lost. Subsequently, when reading this field from the database it creates DateTime with a Utc region (June 10, 2011, 12:30am 0)

Eventually, your client reads the datetime incorrectly.

There are several options to resolve this issue.

1) Convert DateTime to DateTimeOffset in Method parameters as well as in database. This will guarantee that your Local region (ie PST) will be saved in db

2) Use DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified) - this way the kind of DateTime is unspecified and subsequently saved as is in the db.

var timeNow = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified);
serviceClient.SaveTime(timeNow);
var dateTime = serviceClient.GetTime();


回答2:

What presumably comes down in the serialized Json response is a date in the format "milliseconds since the epoch", and should also include timezone information, which the browser is then taking into account when displaying the date relative to the local timezone.

All of this is correct behavior, so there's no bug. It simply seems that you don't want this behavior in your case.

.NET dates have a "Kind" property. If this is not specified, UTC is assumed. The serializer should take the "Kind" property into account when serializing. Try inspecting this property on your object prior to serialization, and changing it to DateTimeKind.Local.

http://msdn.microsoft.com/en-us/library/system.datetime.kind.aspx

Alternatively, you could look at custom deserialization on the browser side, where you'd strip the timezone part off of the serialized date before it's deserialized.