Как бороться с проблемой часового пояса при хранении дат в utc с использованием mongod?

У меня есть коллекция mongodb, где каждый документ имеет некоторые атрибуты и временную метку utc. Мне нужно вытащить данные из коллекции и использовать структуру агрегации, потому что я использую данные из коллекции, чтобы отобразить некоторые диаграммы на пользовательском интерфейсе. Однако мне нужно выполнить агрегацию в соответствии с часовым поясом пользователя. Предполагая, что я знаю часовой пояс пользователя (переданный в запросе из браузера или каким-либо другим способом), есть ли способ использовать структуру агрегации для агрегирования на основе часового пояса [клиента]?

То, о чем вы просите, в настоящее время обсуждается в выпуске MongoDB SERVER-6310 .

Я нашел это в ссылке из обсуждения .

Эта проблема является общей для любой группировки по дате, включая базы данных SQL и базы данных NoSQL. Фактически, я недавно обратился к этой главе в RavenDB. Здесь есть хорошее описание проблемы и решение RavenDB.

Вопросы MongoDB обсуждают обходное решение, подобное тому, что я описал в комментариях выше. Вы заранее рассчитываете местное время, которое вас интересует, и группируйте их вместо этого.

Трудно будет охватывать каждый часовой пояс в мире любым из них. Вы должны выбрать небольшую горстку целевых зон, которые имеют смысл для вашей пользовательской базы, например, подход на офис, описанный в статье RavenDB.

ОБНОВЛЕНИЕ: эта проблема была решена в MongoDB в июле 2017 года (версия 3.5.11). Решение описано в первой ссылке выше, но вкратце они ввели новый формат объекта для дат в выражениях агрегации: { date: , timezone: } который позволяет вам указать часовой пояс для использования при агрегировании , См. Здесь еще один пример в документах Mongo.

Помимо SERVER-6310, упомянутого Мэттом Джонсоном, еще одним обходным решением является использование оператора $project для добавления или вычитания из часового пояса UTC, чтобы «сдвинуть время» в правильную локальную зону. Оказывается, вы можете добавлять или вычитать время в миллисекундах.

Например, если у меня есть поле Date, называемое orderTime . Я бы хотел запросить EDT. Это -4 часа с UTC. Это 4 * 60 * 60 * 1000 миллисекунд.

Поэтому я бы написал следующий outlook, чтобы получить day_ordered по местному времени для всех моих записей:

 db.table.aggregate( { $project : { orderTimeLocal : { $subtract : [ "$orderTime", 14400000] } } }, { $project : { day_ordered : { $dayOfYear : "$orderTimeLocal" } } }) 

Каждый предложенный выше подход работает отлично, но поскольку есть новая версия mongodb, начиная с 2.6, вы можете использовать $let в структуре агрегации, это позволит вам создавать переменные «на лету», тем самым избегая необходимости $project перед группировкой. Теперь вы можете создать переменную с $let которая будет удерживать локализованное время и использовать ее в операторе $group .

Что-то вроде:

 db.test.aggregate([ {$group: { _id: { $let: { vars: { local_time: { $subtract: ["$date", 10800000]} }, in: { $concat: [{$substr: [{$year: "$$local_time"}, 0, 4]}, "-", {$substr: [{$month: "$$local_time"}, 0, 2]}, "-", {$substr: [{$dayOfMonth: "$$local_time"}, 0, 2]}] } } }, count: {$sum: 1} } }]) 

Обратите внимание, что вы используете $let внутри определения блока / переменной, а значение этого блока / переменной – это возвращаемое значение подвыражения "in" , где используются указанные выше вары.

Я нашел решение в плагине mongoose, чтобы нормализовать часовой пояс хранимых дат.

  • Преобразование даты времени UTC в локальное время
  • Как установить часовой пояс java.util.Date?
  • В каком часовом поясе отображается Date.toString ()?
  • Что означает «Z» в отметке Unix «120314170138Z»?
  • Получить время определенного часового пояса
  • Почему вычитание этих двух раз (в 1927 году) дает странный результат?
  • MySQL CONVERT_TZ ()
  • DateTime vs DateTimeOffset
  • Лучшее время для летнего времени и часовых поясов
  • Interesting Posts

    Как создать уведомление с NotificationCompat.Builder?

    Тестирование типа утки с помощью C # 4 для динамических объектов

    Экспорт из sqlite в csv с использованием сценария оболочки

    Как программно перемещать UIScrollView для фокусировки в контроле над клавиатурой?

    Как мы можем восстановить (не возвращать) пароль маршрутизатора?

    Как слить скаляр в вектор без компилятора, теряющего инструкцию обнуления верхних элементов? Ограничение дизайна в встроенных средах Intel?

    Импорт узлов-модhive с помощью TypeScript

    Когда мы можем опустить возвращаемый тип в lambda C ++ 11?

    Каковы правила, определяющие наследование статических переменных в Java?

    Вручную складывать файлы на SD-карту эмулятора Android

    Как узнать, какой процесс блокирует файл с помощью .NET?

    Инъекционная инъекция с использованием Azure WebJobs SDK?

    jQuery DatePicker – изменяет minDate и maxDate на лету

    Использовать проект установки Visual Studio для автоматической регистрации и GAC DLL COM Interop

    Как узнать, имеет ли пользователь iPhone в настоящее время набор паролей и шифрование?

    Давайте будем гением компьютера.