Cercar en aquest blog

21/5/13

Microsoft Virtual Academy

Per qui estigui interessat en formar-se en noves tecnologies i rebre un feedback dels seus coneixements, ús recomano Microsoft Virtual Academy, està realment molt bé.

3/5/13

MongoDB i BsonDateTime, Local o Universal?

Com tots sabeu (o no), MongoDB sempre guarda les dates en format Universal (Utc). Si nosaltres mirem el registres de una col·lecció amb un client tipus MongoVUE, veurem les dates sempre amb aquest format. O sigui, que si per exemple hem implementat un sistema de logs que es guarden en una base de dades MongoDB, la data del log (molt normal que un log proti data) en que s'ha creat, sempre la veurem amb format Utc. Això ens pot agradar o no.

Si no ens agrada, primer em d'entendre que passa. Si per exemple programem en C# i utilitzem el les llibreries de MongoDB per C#, quan volem emmagatzemar una data farem alguna cosa semblat al següent.



BsonDocument par = new BsonDocument();
par.Add("scope"new BsonString(scope));
par.Add("client_app"new BsonString(appName));
par.Add("client_machine"new BsonString(computerName));
par.Add("userName"new BsonString(userName));
par.Add("dateTime"new BsonDateTime(when));
par.Add("exception"BsonDocument.Parse(jsonException));



On "when" és una variable DateTime amb format Local. Però si mirem a la BD, quan queda enregistrada, està el valor Utc. Perquè? Doncs perque MongoDB treballa amb dates Utc. I com ho fa? doncs la classe BsonDateTime interroga la propietat Kind de la data, i si veu que es Local, agafa el valor Utc i l'emagatzema. (when.ToUniversalTime()). Això ho fa sempre al serialitzar una data. I quan llegim de la BD en una aplicació i la deserialitza, agafa la data i la converteix en local.
Correcte!!!, però i si volem veure les dades correctament des del MongoVUE? Com ho fem?? Doncs l'enganyem!! Com? Molt fàcil, modificant el Kind de la data, dient-li que la nostre data ja és universal.

DateTime _when = DateTime.SpecifyKind(when, DateTimeKind.Utc);

i emmagatzemem aquesta.


par.Add("dateTime"new BsonDateTime(_when));


Però cuidado ara al llegir des d'una aplicació, ell automàticament ens la passarà a local, i per tant no ens donarà el valor correcte. Per tant hem de fer el procés invers.
Ara en VB.Net:


 Dim _databona As Date = Date.SpecifyKind(_datamongoDateTimeKind.Local).ToUniversalTime


I això es tot. I amb això mirem on mirem els valors emmagatzemats, sempre veurem una data local.