2013-06-03 11 views
9

Tarih saatlerini UTC olarak kaydeden bir Mongo C# uygulamasına sahibim.Utk ve Yerel veri zamanını Mongo'da saklama

MongoDB.Bson.Serialization.Options.DateTimeSerializationOptions options = 
    MongoDB.Bson.Serialization.Options.DateTimeSerializationOptions.UtcInstance; 

var serializer = 
    new MongoDB.Bson.Serialization.Serializers.DateTimeSerializer(options); 

MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(
    typeof(DateTime), 
    serializer); 

Ayrıca, yerel saat dilimini UTC ile birlikte kaydetmem gerekiyor. ben Yerel mülkiyet ve diğer birinde ilgili UTC değerindeki/Amerikan/Avustralya Diğer/Hint kez saklamak istediğinizi

DateTime WorkItemToCompleteBy{get; set;} 
[BsonDateTimeOptions(Kind = DateTimeKind.Unspecified)] 
DateTime WorkItemToCompleteByLocal{get; set;} 

böyle gider iki özelliklere sahip, açıklamak için. Düzinelerce zaman dilimi ile uğraştığım için, UTC'yi istediğiniz zaman dilime dönüştüren ve WorkItemToCompleteByLocal özelliğinde saklayan bir kod var. Mongo'nun bu değeri 'olduğu gibi' saklamasını ve bana geri vermesini istiyorum. Sorun, Mongo'nun her zaman ISODat olarak saklanması ve değeri Utc sürümüne dönüştürmesidir. Açıklamak. UTC 0730 Saat ve ben 1730Hours Brisbane Zaman hesaplamak ve

"WorkItemToCompleteBy" : ISODate("2013-06-05T07:30:00Z"), 
"WorkItemToCompleteByLocal" : ISODate("2013-06-05T12:00:00Z"), 

Mongo yerel olarak sağlanan zaman yorumladığı

olarak onlar kaydedilmiş olsun, WorkitemToCompleteByLocal için ayarlayın ise sunucu Hindistan'da olmak ve bunu coverts 1200 saat eşdeğer UTC. Değerleri 1730 (IST Albeit) olarak geri alırken Amacımı yener ve Mongo'da herhangi bir yerel zaman bazlı sorgulama yapmamı engeller. Fikirlerin dışındayım. Herhangi bir yardım WorkItemToCompleteByLocal tarihinin 'As-Is' modifikasyonunu

+1

Yeni bir DateTime (Local.Year, Local.Month ......., Kind.Utc) nemlendirerek ve daha sonra kullanarak 'Yerel' saat dilimini UTC olarak yeniden adlandırarak sistemi kandırarak bir iş buldum. bu değer. Şimdi, veriler olduğu gibi saklanıyor ve mantığımın, yerel sütunun türünün ne olduğuna bakmaksızın yerel değeri depoladığını bilmesi (benimsenen çalışma yüzünden UTC olduğunu söylüyor). Daha iyi bir cevap bulana kadar bunu kullanacağım. –

+0

MongoDB'nin JIRA'sına yerel saatlerle ilgili bir öğe ekledim, bu da bu SO girişine işaret eder (bir kayıt gerektirir): https://jira.mongodb.org/browse/DOCS-4086 – akauppi

+0

Bkz. Http: //stackoverflow.com/a/38934986/194717 – Tony

cevap

2

Yeni sürüm =>

public class MyMongoDBDateTimeSerializer : DateTimeSerializer 
{ 
    // MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic 
    // We overwrite it to be DateTimeKind.Unspecified 
    public override DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) 
    { 
     var obj = base.Deserialize(context, args); 
     return new DateTime(obj.Ticks, DateTimeKind.Unspecified); 
    } 

    // MongoDB stores all datetime as Utc, any datetime value DateTimeKind is not DateTimeKind.Utc, will be converted to Utc first 
    // We overwrite it to be DateTimeKind.Utc, becasue we want to preserve the raw value 
    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value) 
    { 
     var utcValue = new DateTime(value.Ticks, DateTimeKind.Utc); 
     base.Serialize(context, args, utcValue); 
    } 
} 
21

depolamaya yardımcı olmak için takdir edildi. Bu, MongoDB'yi ham değeri depolamaya ve DateTimeKind özniteliğini DateTime nesnesinde görmezden gelmeye zorladığım yoldur.

Bu, iş mantığınız için geçerli olmayabilir, ancak belirli nedenlerden dolayı bizim için mantıklıdır. .net sürücü sürümü 2.4 olarak

BsonSerializer.RegisterSerializer(typeof(DateTime), new MyMongoDBDateTimeSerializer()); 


public class MyMongoDBDateTimeSerializer : DateTimeSerializer 
{ 
    // MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic 
    // We overwrite it to be DateTimeKind.Unspecified 
    public override object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, System.Type nominalType, MongoDB.Bson.Serialization.IBsonSerializationOptions options) 
    { 
     var obj = base.Deserialize(bsonReader, nominalType, options); 
     var dt = (DateTime) obj; 
     return new DateTime(dt.Ticks, DateTimeKind.Unspecified); 
    } 

    // MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic 
    // We overwrite it to be DateTimeKind.Unspecified 
    public override object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, Type actualType, MongoDB.Bson.Serialization.IBsonSerializationOptions options) 
    { 
     var obj = base.Deserialize(bsonReader, nominalType, actualType, options); 
     var dt = (DateTime)obj; 
     return new DateTime(dt.Ticks, DateTimeKind.Unspecified); 
    } 

    // MongoDB stores all datetime as Utc, any datetime value DateTimeKind is not DateTimeKind.Utc, will be converted to Utc first 
    // We overwrite it to be DateTimeKind.Utc, becasue we want to preserve the raw value 
    public override void Serialize(MongoDB.Bson.IO.BsonWriter bsonWriter, System.Type nominalType, object value, MongoDB.Bson.Serialization.IBsonSerializationOptions options) 
    { 
     var dt = (DateTime) value; 
     var utcValue = new DateTime(dt.Ticks, DateTimeKind.Utc); 
     base.Serialize(bsonWriter, nominalType, utcValue, options); 
    } 
} 
C# sürücünün
+3

2,0.1 – Vaibhav

+1

'da MongoDB.Bson.Serialization.IBsonSerializationOptions öğesini bulamıyor gibi görünüyor. C# sürücüsü [BsonDateTimeOptions (Kind = DateTimeKind.Utc)] 'ye saygılı olsa bile, bu çözüm çoğu geliştirme kullanımı örneğinde daha iyi olacaktır çünkü her birini belirtmek zorunda kalmadan, tüm DateTime özelliklerine global olarak ve otomatik olarak uygulanacaktır. kaçınılmaz olarak birini unuttuğunuzda hatalar. –

0

, bunu kullanın:

using MongoDB.Bson.Serialization; 
using MongoDB.Bson.Serialization.Serializers; 

BsonSerializer.RegisterSerializer(DateTimeSerializer.LocalInstance); 

Bu şekilde tarih saat değerleri tür = UTC ile saklanacaktır db, ancak yerel türden serpiştirilmiş.

İlgili konular