Хранение Utc и Local datetime в Монго

У меня есть реализация Mongo C #, которая хранит дату и время как UTC.

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);

У меня также есть необходимость хранить локальный часовой пояс пользователя вместе с UTC. Чтобы объяснить, у меня есть два свойства, которые выглядят как

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

Я хотел бы хранить австралийское / американское / индийское / другое время в свойстве Local и соответствующее значение UTC в другом. Поскольку я имею дело с десятками часовых поясов, у меня есть код, который преобразует UTC в нужный часовой пояс и сохраняет его в свойстве WorkItemToCompleteByLocal. Я'Я хотел бы, чтобы Монго сохранил это значение.как есть' и верни это мне. Проблема в том, что Mongo всегда сохраняет его как ISODate и преобразует значение в версию Utc. Объяснить. Если UTC - 07:30, а я вычисляю время Брисбена до 17:30 и устанавливаю его равным WorkitemToCompleteByLocal, они сохраняются как

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

Монго интерпретирует предоставленное время как местное,сервер находится в Индии и покрывает это к эквивалентному UTC 1200 часов. В то время как он возвращает значения как 1730 (IST Albeit), он побеждает мою цель и мешает мне запускать любые запросы, основанные на локальном времени в Mongo. У меня нет идей. Мы ценим любую помощь, чтобы помочь сохранить дату WorkItemToCompleteByLocal 'Как есть' без изменений

 Tony06 апр. 2017 г., 19:13
 akauppi25 сент. 2014 г., 14:17
мы добавили элемент в MongoDB 's JIRA по работе с местным временем, которая также относится к этой записи SO (требуется регистрация):jira.mongodb.org/browse/DOCS-4086
 LIFE REFACTORED03 июн. 2013 г., 19:13
Я нашел способ обойти систему, переписавМестный' часовой пояс как UTC, гидратируя новый DateTime (Local.Year, Local.Month ......., Kind.Utc) и затем используя это значение. Теперь данные хранятся как есть, и моя логика знает, что локальный столбец хранит локальное значение независимо от того, что говорит тип (он говорит UTC из-за принятого обходного пути). Я буду использовать это, пока не найду лучший ответ.

Ответы на вопрос(3)

ирую атрибут DateTimeKind в объекте DateTime.

Это может не относиться к вашей бизнес-логике, но имеет смысл для нас по нашим конкретным причинам.

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);
    }
}
 J.T. Taylor03 нояб. 2016 г., 19:36
Отличный подход. Даже если драйвер C # будет учитывать [BsonDateTimeOptions (Kind = DateTimeKind.Utc)], это решение будет лучше в большинстве случаев использования разработки, поскольку оно будет применяться глобально и автоматически ко всем свойствам DateTime, а не указывать каждое из них, а затем иметь ошибки, когда вы неизбежно забудете одну.
 Vaibhav28 сент. 2015 г., 14:54
Безразлично»Кажется, что в 2.0.1 нет MongoDB.Bson.Serialization.IBsonSerializationOptions

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

BsonSerializer.RegisterSerializer(DateTimeSerializer.LocalInstance);

Таким образом, значения даты и времени будут храниться с kind = utc в дБ, но десериализованы в локальном виде.

Решение Вопроса

    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);
    }
}

Ваш ответ на вопрос