Уважаемые Хабравчане, решил поделиться с Вами техническим решением некоторых интересных и на первый взгляд не очевидных проблем. Всю жизнь я в основном только черпал информацию, читал замечательные статьи (в том числе на Хабре) очень помогавшие мне в решении тех или иных технических проблем. Но в последние 2 года, занявшись разработкой своей облачной платформы для автоматизации предприятий, мне пришлось решать довольно много задач “впервые”, т.е. которые если кто-то и решал, то описания (даже близко) я не находил. В связи с этим я решил написать 3 цикла статей: цикл по базам данных, цикл по безопасности и цикл по системам автоматизации. Эта статья — первая статья первого цикла.

Краткая формулировка задачи: каким-то образом current_date, current_time и current_timestamp должны выдавать дату-время в зависимости от настроек в аккаунте пользователя и при этом на самом сервере будет стоять московское время.

Система задумывалась неограниченно масштабируемая, с огромным числом потенциальных пользователей в любом регионе нашей необъятной страны, в какой-то момент встал вопрос, а удобно ли будет пользователям, например во Владивостоке, работать в системе с московским временем. Сервера то находятся в Москве, на них стоит московское время, при этом каждому пользователю (не важно, из какого он региона) выделяется несколько своих (индивидуальных) баз данных и все они находятся, грубо говоря, на одном сервере. Делать под каждый часовой пояс свой сервер глупо, да и не возможно с точки зрения концепции системы, ибо любой пользователь в любой момент может часовой пояс поменять.

Тип базы данных используемых в текущий момент – firebird 3

После суток метаний и изучений мануалов, найдено было следующее простое решение. Было создано 3 простых VIEW:

CREATE OR ALTER VIEW D_CURRENT_DATE(DD)
AS
SELECT cast((current_timestamp+0.000000000000000)as date) as dd FROM RDB$DATABASE;

CREATE OR ALTER VIEW D_CURRENT_TIME(DD)
AS
SELECT cast((current_timestamp+0.000000000000000)as time) as dd FROM RDB$DATABASE;

CREATE OR ALTER VIEW D_CURRENT_TIMESTAMP(DD)
AS
SELECT (current_timestamp+0.000000000000000) as dd FROM RDB$DATABASE;

Приведенные выше VIEW — для московского времени, которое стоит по умолчанию. Если пользователь выбирает часовой пояс отличный от московского, например “UTC+7 Красноярское время”, php-шный скрипт (при помощи которого пользователь это выбирает) изменяет VIEW в его БД следующим образом.

CREATE OR ALTER VIEW D_CURRENT_DATE(DD)
AS
SELECT cast((current_timestamp+0.166666666666667)as date) as dd FROM RDB$DATABASE;

CREATE OR ALTER VIEW D_CURRENT_TIME(DD)
AS
SELECT cast((current_timestamp+0.166666666666667)as time) as dd FROM RDB$DATABASE;

CREATE OR ALTER VIEW D_CURRENT_TIMESTAMP(DD)
AS
SELECT (current_timestamp+0.166666666666667) as dd FROM RDB$DATABASE;

Соответственно, из базового current_timestamp, будет прибавляться (либо вычитаться) количество часов, в зависимости от того часового пояса, который выбирает пользователь.

Далее везде, в коде всех скриптов, процедур, триггеров вместо current_timestamp пишется всегда d_current_timestamp. Благодаря этому, во всех записях в БД всегда будет проставляться время пользователя, а не московское, несмотря на то, что все базы данных на одном сервере с московским временем.
Поделиться с друзьями
-->

Комментарии (38)


  1. lair
    15.12.2016 12:11
    +7

    Краткая формулировка задачи: каким-то образом current_date, current_time и current_timestamp должны выдавать дату-время в зависимости от настроек в аккаунте пользователя и при этом на самом сервере будет стоять московское время.

    Зачем?


    В БД должны храниться данные в известном часовом поясе, а при вводе/выводе они должны конвертироваться в тот часовой пояс, который нужен пользователю.


    (есть случаи, когда конвертация не имеет смысла, но это тема для отдельного обсуждения)


    1. gsaw
      15.12.2016 12:37

      Ну видимо не хотелось переписывать софт, который разрабатывали Масквичи. Мне интересно, они там дату разных пользователей сверяют? Это же ад должен быть.


    1. DigitalSmile
      15.12.2016 16:50

      Абсолютно верно. Решали похожую задачу по хранению даты с таймзоной в базе (вообще думал что она распространенная и не должна вызывать сложностей). Вкратце: делим всю дату на 2 части, первая часть timestamp типа long, вторая часовой пояс (буквенное выражение или отклонение в часах, в зависимости от задачи). На клиент возвращается объект из двух частей и строится нужная дата со смещением.


    1. mail-online
      15.12.2016 17:08

      Ну это неверное зависит от величины проекта. Вот представьте, у Вас один сервер с файрбердом, на нем 1000 баз пользователей, и у каждого пользователя его данные должны отображаться в его часовом поясе (который он настроит). При этом у вас php кода самой системы 3 мегабайта и половина из них запросы в БД, куча процедур и триггеров в каждой из БД, причем структура у каждого пользователя может отличаться, т.к. есть встроенный язык программирования для пользователей (аля как в 1С только немного глубже и через веб). И вы хотите в каждом месте делать доп манипуляции с датой? Это будет жесть. Механизм должен быть универсальный и простой.


      1. lair
        15.12.2016 23:18

        И вы хотите в каждом месте делать доп манипуляции с датой?

        Не в каждом, а в одном слое (скорее всего, в UI). Просто то, что вы описываете, выглядит как плохо спроектированная система.


        1. mail-online
          15.12.2016 23:25

          Ну так и сделано, в UI и делается собственно. А в селекте уже никаких расчетов делать не надо, он просто получает уже нужную дату, т.к. она записана в базе при UI. В селекте может тоже использоваться, например в некоторых фильтрах по умолчанию, но это все обернуто в процедуру внутри БД обычно, а там везде через view любая текущая дата.


          1. lair
            15.12.2016 23:54

            Ну так и сделано, в UI и делается собственно

            По вашему описанию — делается в БД. А БД — это не UI.


            (я еще стесняюсь спросить, что будет, если с одной БД будут одновременно работать несколько пользователей, каждый из которых хочет свой часовой пояс)


            1. mail-online
              16.12.2016 01:23

              1. Возможно мы неправильно друг друга поняли. Я подумал что UI по вашему это Update и Insert.
              Смысл в том что все даты в добавлениях и апдейтах делаются через эти view, а в селекте нам уже не нужна математика никакая… там уже дата записана с учетом часового пояса.

              2. Если мы рассматриваем мою систему, то тут не совсем корректно сопоставление пользователи — часовые пояса. Есть компании, у которых есть сотрудники. Каждой компании выдается аккаунт и вот на этот аккаунт своя база данных и тут можно выставлять часовой пояс. Все сотрудники компании которые работают в ее аккаунте, работают с настройками компании в целом, т.е. с часовым поясом который настроен у компании.


              1. lair
                16.12.2016 11:18

                Я подумал что UI по вашему это Update и Insert.

                Нет, UI — это User Interface.


                Смысл в том что все даты в добавлениях и апдейтах делаются через эти view, а в селекте нам уже не нужна математика никакая…

                Ага. А теперь представьте, что вам надо посчитать продолжительность выполнения задачи, которая начата до перевода времени с летнего на зимнее, а закончена — после.


                Все сотрудники компании которые работают в ее аккаунте, работают с настройками компании в целом, т.е. с часовым поясом который настроен у компании.

                Как мило. У компании один склад в Калининграде, второй в Иркутске. И как время выдачи товара фиксировать будем?


                1. mail-online
                  17.12.2016 15:05

                  lair, соглашусь, в чем то вы правы. Приятно, когда конструктивная критика.

                  У компании один склад в Калининграде, второй в Иркутске. И как время выдачи товара фиксировать будем?


                  Согласен, это проблема. Вы заставили меня задуматься над ней. Но она точно не решится индивидуальной постановкой UTC сотруднику. Она решится индивидуально постановкой UTC складу! Нельзя чтобы данные склада отображались в UTC сотрудника, ведь для каждого сотрудника дата-время приема или выдачи товара будет отображаться разное — чего быть не должно (оба позвонят начальнику и скажут: один что товар выдан в 10.00, другой что в 12.00 :) и кому верить?). При этом на UTC компании это тоже не должно быть завязано — оно может быть совершенно другим. Т.е. склад — это просто отдельный модуль с индивидуальным UTC у каждого склада.

                  Потом есть еще одна причина почему нельзя давать сотрудникам индивидуальный UTC, и он должен быть у компании. В частности у меня в системе можно помимо подразделений объединять сотрудников в группы, например в одном подразделении службы сети связи может быть группа сотрудников занимающийся телефонией, группа занимающиеся интернетом, телевидением и т.д. И можно например настроить чтобы задача с типом интернет пришла в это подразделение автоматически данной группе, и даже распределилась ее сотрудником по какому-то алгоритму. Может так быть, что в группу объединяются сотрудники из разных подразделений, но работающие над одной задачей каждый со своей стороны. Для этих групп могут ставиться задачи именно на группы со многими различными алгоритмами распределения, на группы могут формироваться графики работ (именно группы). Есть для групп SCRUM доски.
                  И вот представьте ситуацию, у одного сотрудника из группы стоит один UTC, а у другого другой! И какой при этом UTC отображать в графике группы в которую входят оба сотрудника? Это просто билеберда получится.
                  При этом я согласен с вами, что если один работает в Калининграде а второй в Иркутске… возможно надо просто глубже делать деление системы, вводит понятия офисов, где должно быть свое UTC и при этом запрещать программно объединять сотрудников из разных офисов. В общем действительно надо подумать.
                  Тут еще видимо есть у меня и дополнительная проблема, у меня в системе встроенный язык программирования (свой) и вся внутренняя кухня аккаунта сделана на нем, а все php-шное — это фактически интерпретатор, поэтому индивидуальный UTC на каком-то модуле должен реализовываться на уровне программирования на внутреннем языке, а не на интерпретаторе или базе данных.

                  Но вы действительно правы, рано или поздно вопрос разных UTC в каких-то модулях в рамках одной компании может встать и над этим надо подумать. Но так вот в лоб эта проблема не решается т.к. есть миллион дополнительных нюансов.
                  Пока я все таки считаю свой подход (UTC на компанию) правильным, в данной ситуации, но возможно его придется глубже модернизировать.
                  Спасибо за конструктивную критику. Она действительно полезна.

                  По поводу
                  А теперь представьте, что вам надо посчитать продолжительность выполнения задачи, которая начата до перевода времени с летнего на зимнее, а закончена — после.

                  Если будет необходим такой подсчет, то такой его нюанс можно реализовать программно. Момент перевода времени известен, сделать IF в процедуре, например если время перевода попадет между датами начала и конца — прибавить к продолжительности час (или вычесть — по ситуации). В общем тут я проблемы не вижу.


                  1. lair
                    17.12.2016 21:43
                    +1

                    Вы, похоже, не понимаете, что такое UTC.


                    оба позвонят начальнику и скажут: один что товар выдан в 10.00, другой что в 12.00 :) и кому верить?

                    Никому не верить, верить системе, которая скажет, что товар выдан в 11 по времени склада.


                    И какой при этом UTC отображать в графике группы в которую входят оба сотрудника?

                    Каждому сотруднику надо отображать тот часовой пояс, который ему удобнее с точки зрения бизнеса.


                    Тут еще видимо есть у меня и дополнительная проблема, у меня в системе встроенный язык программирования (свой) и вся внутренняя кухня аккаунта сделана на нем, а все php-шное — это фактически интерпретатор, поэтому индивидуальный UTC на каком-то модуле должен реализовываться на уровне программирования на внутреннем языке, а не на интерпретаторе или базе данных.

                    Не совсем так. Корректные операции со временем, несомненно, должны быть заложены в бизнесовый язык, но при этом UI должен поддерживать отображение в том часовом поясе, в котором удобно.


                    Если будет необходим такой подсчет, то такой его нюанс можно реализовать программно. Момент перевода времени известен, сделать IF в процедуре, например если время перевода попадет между датами начала и конца — прибавить к продолжительности час (или вычесть — по ситуации). В общем тут я проблемы не вижу.

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


  1. Refridgerator
    15.12.2016 12:50
    +4

    А почему в качестве точки отсчёта выбрано московское время, а не UTC?


    1. mail-online
      15.12.2016 17:12

      Потому что они в Москве физически. Так удобнее, помимо самих баз данных пользователей есть еще куча служебных вещей.


  1. barker
    15.12.2016 14:34

    Вы решаете проблему, которая возникла из-за того, что вы (или кто-то) что-то неправильно делали изначально. Зачем вообще надо хранить время в любом локальном (naive, не-aware, итд) времени, вот как должен вопрос ставиться. Если датавремя представляет конкретную точку во врмени, то оно всегда должно храниться в БД вместе с таймзоной, либо просто подразумеваться UTC (что предпочтительнее и не отменяет первого варианта).


    1. mail-online
      15.12.2016 17:21

      Это сложно. Представляете в 3 мб php кода (половина их которого гигантские sql запросы) Вам надо везде делать операции преобразования времени! В детсяти тысячах мест! А так Вам не надо задумываться над всем этим, все в базе данных решено уже. Да и лишние операции, быстродействие ниже и т.д. (хоть это и копейки). И например у нас реализовано программируемое API, т.е. пользователь может в своей БД создать триггер специальный, который передаст инфорамцию во вне. В этом случае там будет время по МСК? Или принимать данные извне как? В общем много причин почему сделано так.

      Но я как бы не претендую на правильность. Я просто описал способ как это можно сделать, кому-то понравится, а кто-то придумает как сделать по своему. Но данный способ оказался наиболее простым и эффективным.


      1. barker
        15.12.2016 20:29
        +2

        Это не сложно, это единственный правильный путь работы со временем.
        Это должно делаться (и у всех делается) в одном месте — в той или иной прослойке, которая у вас работает с БД. В большинстве бд-фреймворках/орм итд всё это есть искаропки, конечно, потому что по-другому просто нельзя.

        В этом случае там будет время по МСК? Или принимать данные извне как?
        Пусть хоть по тихоокеанскому, время никогда нельзя передавать, обрабатывать и хранить без привязанной таймзоны (или подразумевания что там UTC, что очевидно для случая, например, типа unixtime). Нет понятия «время по МСК», время оно и есть время — просто временной штамп. По МСК оно может стать при показе его в этой таймзоне. Нет, можно и передавать его по МСК и даже хранить (только непонятно зачем), но надо тогда так и оперировать везде «01.02.2016 22:22:58; МСК», потому что нет времени «01.02.2016 22:22:58» — это не время, а билиберда.
        Так же всё и про «принимать извне».


      1. barker
        15.12.2016 20:42

        Не, я просто ещё раз прочитал всё, и не могу понять — у вас в конкретной колонке в БД в каком виде лежит время? Во всех в «московской таймзоне» а вы просто во вьюхах его конвертируете и отдаёте наружу? Просто вот это конкретно сбивает с толку: «Благодаря этому, во всех записях в БД всегда будет проставляться время пользователя, а не московское». Все именно от этого в ужас пришли. Это надо подробнее объяснить вам, потому что не верится в такое.
        У юзера сейчас рисуется допустим 12:00 для какой-то сущности, если юзер меняет таймзону (допустим соседнюю на час) то он увидит теперь везде 13:00? Правильно же? Тогда как это делается с учётом, что в БД неизвестное время неизвестной таймзоны?


        1. mail-online
          15.12.2016 22:59
          -1

          Нет, view используется при запаси или изменении данных. Селект при этом будет обычный, и в нем уже будет время пользователя. В этом то и преимущество. Никакой дополнительной математики при выводе данных.
          Если вы боитесь что при изменении часового пояса может получится белеберда с записями в старом часовом поясе, то во первых такие изменения делает только администратор аккаунта, во вторых это как правило разово (разве что компания решит куда-то переехать), в третих ведутся логи изменений, т.е. можно посмотреть когда было изменение часового пояса и с какого на какой и понять что откуда растет. Я в этом не вижу проблемы. Ну зачем компании больше одного раза менять часовой пояс? Они же сами себе хаос делают…


          1. vasyakrg
            16.12.2016 06:12

            Вот тут немного не понял…
            Поясните пожалуйста логику работы программы при таком случае: сегодня я в Петропавловске, а завтра в Петрозаводске. Сегодня я начал забивать отчёт, а завтра хочу его расширить новыми данными. Какое время мне инсентировать и какое я буду видеть на экране, когда вернусь в Москву?


            1. mail-online
              17.12.2016 20:58

              Ну если мы рассматриваем мою систему, то есть аккаунт компании, аккаунту выделяется база данных и в настройках можно выставить часовой пояс (для компании). При изменении настроек сформируются соответствующие view в БД и будет в дальнейшем писаться соответствующее время, где бы сотрудник не находился, хоть в антарктиде если там есть интернет. В общем неважно где вы физически, время будет — тот момент когда вы сделаете запись по московскому времени (в моем случае) скорректированное до часового пояса из настроек.

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


              1. michael_vostrikov
                18.12.2016 05:35

                Статью я написал потому, что в свое время я не нашел нигде описанного способа как такое сделать

                Может потому что так никто не делает?) Дело не в том, что у вас правильный или неправильный вариант реализации, вам пытаются объяснить, что сам подход неправильный, независимо от того, как он реализован. Как-то даже странно, что при проектировании системы "с огромным числом потенциальных пользователей в любом регионе" работа с временными зонами была недостаточно продумана.


                Как я понял, между базой и пользователем у вас есть прослойка на PHP. Скорее всего, там есть какая-нибудь функция query(), которая выполняет запросы на чтение. Вот там после запроса можно пробегаться по полям результата и для полей datetime и timestamp делать конвертацию в таймзону пользователя. А в базе все хранить в одной фиксированной таймзоне с известным смещением (неважно, в UTC или по Москве).


                1. mail-online
                  18.12.2016 11:29

                  Ну на самом деле на php у меня — интерпретатор, структура конфигурации аккаунта хранится в самой базе и интерпретируеся при выводе страницы, пользователю предоставляется специальный язык программирования для конфигурирования аккаунта (и базы данных и веба), вот там как раз создаются и компилируются процедуры и триггеры в БД.
                  В php как вы описали — делать не вариант, учитывая то, что пользователь строит сам конфигурацию, вы никогда не угадаете что это дата которую надо форматнуть (вернее угадаете, но не понятно зачем такие сложности то вообще и дополнительное процессорное время). Если так и делать то надо обрабатывать не результаты вывода query(), а в самом поле sql. Т.е. на уровне компилирования процедур на внутреннем языке. Собственно, грубо говоря, так и сделано, только через VIEW.
                  Почему неправильно делать именно каждому пользователю свой UTC (а надо делать компании) я описывал уже подробно «mail-online 17 декабря 2016 в 15:05» (CTRL-F сделайте)

                  Кстати, может кто знает, в битриксе, мегаплане, клиентской базе и т.д. есть настойка часового пояса вообще? Я например обыскал все настройки в битриксе — я не нашел… У меня есть такое подозрение, что никто не просто так не делает, а никто вообще не сделал такого в принципе.


                  1. lair
                    18.12.2016 14:24

                    что пользователь строит сам конфигурацию, вы никогда не угадаете что это дата которую надо форматнуть

                    Зачем угадывать-то, когда достаточно ввести правильный тип данных.


                    У меня есть такое подозрение, что никто не просто так не делает, а никто вообще не сделал такого в принципе.

                    Да ладно. В Jira это есть, скажем. В любом приличном современном мессенджере это есть.


                    (ну и в ERP-системе, в разработке которой я участвую, тоже есть, чего уж)


                  1. michael_vostrikov
                    18.12.2016 15:56

                    оба позвонят начальнику и скажут: один что товар выдан в 10.00, другой что в 12.00

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


                    И вот представьте ситуацию, у одного сотрудника из группы стоит один UTC, а у другого другой! И какой при этом UTC отображать в графике группы в которую входят оба сотрудника?

                    В графике (в БД) время хранится в фиксированном часовом поясе. Каждому сотруднику он отображается в его часовом поясе. Чтобы сотрудник знал, что информация "в 12:00 мне позвонят из города N" это по его локальному времени.


                    вы никогда не угадаете что это дата которую надо форматнуть (вернее угадаете, но не понятно зачем такие сложности)

                    Насколько я понял из документации, ibase_field_info() возвращает информацию о типе поля в результате запроса. Особых сложностей тут нет, а надо все это, чтобы правильно учитывать время и правильно его отображать. Без ограничений бизнес-логики типа "и при этом запрещать программно объединять сотрудников из разных офисов".


                    Если так и делать то надо обрабатывать не результаты вывода query(), а в самом поле sql

                    Если так делать, то надо это делать в представлении при рендеринге значения со временем (заодно и формат можно задать, "d.m.Y" или "m.d.Y" или любой другой):


                    <td><?= $formatter->asDatetime($row['created_at']) ?></td>


        1. mail-online
          15.12.2016 23:05

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


        1. mail-online
          15.12.2016 23:10

          У юзера сейчас рисуется допустим 12:00 для какой-то сущности, если юзер меняет таймзону (допустим соседнюю на час) то он увидит теперь везде 13:00? Правильно же?


          Нет, юзер увидит 12.00 везде. В старых записях все останется по прежнему. Но новая запись будет не 12.01 а уже 13.01 в случае +1 в таймзоне.


          1. barker
            16.12.2016 12:24

            Нет, юзер увидит 12.00 везде.
            Это же катастрофически неправильно. 12:00 в соседней таймзоне это не 12:00 же.
            Или обратное: То есть юзер создал в 12:00 запись. Потом мгновенно переместился в соседнюю таймзону и создал запись и у вас в БД запишется две записи:
            12:00
            13:00
            И потом он будет видеть эти два времени в таком виде из любой таймзоны? Несмотря на то, что на самом деле это одно и то же время?

            Теперь более реальный случай: юзер из Челябинска (+05:00) такой в 12:00 создал запись и видит 12:00, о, думает всё нормально. А теперь в эту же запись (в это время или же назаватра) смотрит юзер из Москвы (+03:00) и какое время он видит то? 12:00 что ли? Если 12:00, то это жесть полная. Если 10:00 то как раз в этом вопрос — непонятно как это сделано, если, блин, вы не знаете что такое 12:00 на самом деле и в какой таймзоне («локальное время пользователя»).


            1. Scarred
              17.12.2016 20:59

              Мне кажется что подразумевается: компания работает только в одном часовом поясе, сотрудников из другого часового пояса не будет (либо они работают по времени компании).
              Ну а с законодательным изменением часовых поясов еще не сталкивались, разработка началась после последнего изменения.


            1. mail-online
              17.12.2016 21:08
              -1

              Нет. Если мы рассматриваем мой случай, то таймзона меняется для аккаунта. Аккаунт выдается для компании в которой работают сотрудники, и на этот аккаунт как раз выделяется база данных в которых прописываются данные view. Если оба сотрудника (юзера) работают в этом аккаунте, то время их записи будет отображаться в таймзоне аккаунта. Если стоит таймзона Челябинска (+5) и юзер из москвы сделал запись в 12:00 (+3) по своему времени, то в БД запись будет 14:00 и откуда бы и кто бы не смотрел это будет запись 14:00 всегда. Всегда в UTC Челябнска откуда бы она сделана не была.


              1. lair
                17.12.2016 21:45
                +1

                Всегда в UTC Челябнска откуда бы она сделана не была.

                Маленький хинт: UTC Челябинска ничем не отличается от UTC Москвы, и в обоих них эта запись будет отражаться в 9:00.


              1. barker
                19.12.2016 07:16

                Всегда в UTC Челябнска откуда бы она сделана не была.
                Это шутка такая или вы реально не понимате даже что такое UTC???


  1. michael_vostrikov
    15.12.2016 15:08

    Вы бы описали подробнее свое приложение, а то выглядит как будто вы сначала создали себе проблему, а потом героически ее решили, притом непонятно с какой целью.
    У вас не бывает случая, когда несколько пользователей работают с одной БД? Почему обязательно нужна конвертация на стороне БД, а не в PHP? И кстати почему вью, а не процедура?


    1. rico_spb
      15.12.2016 17:13

      View, по смыслу легче процедур, и лучше обрабатываются оптимизатором.


    1. mail-online
      15.12.2016 17:31

      это облачная платформа erp-platforma.com, с системой автоматизации для предприятий, типа битрикса если в курсе что это такое, только круче, т.к. есть встроенный язык программирования и каждый пользователь может сам настраивать свою БД или веб интерфейс в аккаунте, ну и куча фишечек и плюшечек типа SCRUM досок, программируемого API и т.п. + универсальная система задач, которая подходит даже для провайдеров. Но это не суть важно т.к. все настолько универасально, что каждый пользователь может создать себе любой модуль сам, хоть бухгалтерию написать…

      Т.к. все универсально и индивидуально, то каждому пользователю и выделяется своя БД, вернее даже 4 штуки, основная, файловая, для безопасных ссылок и бд для логов. Я некоторые из технических реализаций этих вещей в следующих статьях буду описывать. Еще много всего интересного можно написать, следующая думаю будет звучать «Как вести логи изменений данных пользователями в базе данных, сохраняя их в другой базе данных (чтобы основная база данных не засорялась мусором и не росла)» — интереснейшая вещь была с технической точки зрения.

      View — так проще, как в запросе вы процедуру планируете использовать, left join? это неудобно, а тут просто вместо например timestamp пишете d_timestamp и все работает.


  1. TerraV
    15.12.2016 17:22
    +1

    Простите, наболело, но руки оторвать за такую работу с датами. Дата сама по себе не имеет привязки к часовому поясу это тупо Long. К часовому поясу привязано представление даты (строка, виджет). Можно использовать концепцию Model-View, где сама дата это модель, а строка или виджет на форме это представление. Как только вы начинаете модифицировать дату, ваш код становится некорректным. В транспорте дата это или Long, или строка но обязательно с таймзоной.

    >> Благодаря этому, во всех записях в БД всегда будет проставляться время пользователя => а потом примут закон о смещении часовых поясов и корректность прошлых данных накроется медным тазом.


    1. vasyakrg
      16.12.2016 06:15

      Вот тоже подумал про законные смещения. У нас за последний десяток лет два раза принимали закон о переходе на час и, соответственно, о не переходе. В итоге, когда я захочу получить срез данных за последние пять лет — я не понятно что увижу…


      1. mail-online
        17.12.2016 21:17

        Ну она в любом случае накроется если это случиться. Разобраться что за последние 5 лет творилось с часовыми поясами и переходами на летне-зимнее время… так там чет ногу сломит. Но мне кажется это на самом деле не критично, ибо на фоне 5 лет час туда сюда сколько процентов занимает? Час это 1/43800. Это потеря точности 0.0022831%
        Тут конечно вопрос что вам необходимо, но проработав 10 лет в телекоме я никогда не сталкивался с тем чтобы делать подобные анализы и тем более со 100% точностью. Детализации делали, да, но там юникстайм который был на оборудовании и никто не заморачивался. В случае перехода на зимнелетнее время получалось что траифк писался 2:59, потом 2:00. Грубо говоря час накладывался друг на друга (или был промежуток в другом случае)


        1. lair
          17.12.2016 21:45
          +1

          Но мне кажется это на самом деле не критично,

          Это вам так кажется, пока этот час внезапно не выпадает на смену дня, и у вас в документе написана одна дата, а в системе — другая.