3

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.

Archil Kublashvili
  • 696
  • 1
  • 8
  • 20

2 Answers2

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.

Ash Eldritch
  • 1,504
  • 10
  • 13
  • Pretty much spot on but If I remember correctly you need to set it to DateTimeKind.Unspecified so that times are not altered when serializing/deserializing across timezone boundaries. – David Steele Jun 20 '11 at 11:19
  • When I inspect "Kind" property on my object prior to serialization it is set to Unspecified. – Archil Kublashvili Jun 22 '11 at 08:19
2

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();
Boris Lipschitz
  • 9,236
  • 5
  • 53
  • 63
  • This all makes total sense and I feel that's exactly what is happenning. However, I have tried solution 2 that you suggest but with no luck. I have tried all cominations of DateTimeKind both when saving and reading from DB but I still get the delta on the client. In fact, I am not sure why I need to specify anything when saving a datetime value to the DB. When I look in the table the value is 2011-06-10 00:00:00.000 (i only used 12:30 in the example above to avoid confusion but i do set time to 00:00 am). So when reading it I have tried Local, Utc and Unspecified but I still get delta of -7. – Archil Kublashvili Jun 22 '11 at 08:16
  • In the following example I'm using wcf and there is entity framework on sql azure side. var timeNow = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified); serviceClient.SaveTime(timeNow); var dateTime = serviceClient.GetTime(); the resulted dateTime has Kind equals Unspecified. And it works "on my machine" – Boris Lipschitz Jun 23 '11 at 07:29
  • I took into account what you said about Azure dates and solved the problem in javascript itself by doing this: var dd = new Date($idDueDate.val()); oPrediction.DueDate = new Date(dd.toUTCString()); before actually saving to the db. The dates were getting changed by Azure exactly as you described above. Thanks everyone. – Archil Kublashvili Jun 28 '11 at 11:12