суббота, 12 сентября 2015 г.

Время

В посте "Статистика без "Статистика"" я упоминал об одном "пеньке" и обещал отдельную тему. Для начала настоятельно рекомендую прочитать статью "Григорианский календарь" на Википедии или другом ресурсе. Проблема (в том числе и 2000) не в самом времени, а в его учёте, обозначении и многочисленных форматах хранения. В АС-Библиотека-3 внутренний формат хранения даты "Офисный". Иными словами это число с плавающей точкой. Целая часть - кол-во дней с 01.01.1900. А дробная - часть дня.
В строках Марк записей даты представлены различными форматами времени в виде обычных символьных строк и здесь мы их не рассматриваем.
Сразу после перехода на MS SQL обнаружилась одна проблема - при SQL запросе происходит сдвиг ровно на двое суток. Конкретно - преобразование числа, представляющего дату, в дату получаем дату на двое суток больше, чем должно представлять число. При этом никаких проблем в работе модулей не возникало. Всё работало корректно.
Вот пример.



Здесь ячейка слева в формате даты, а справа - в формате числа. Правая ячейка равна левой. Преобразуем это число в дату SQL запросом в Access (воспользуемся "Администратором").



Дата совпадает - 28 августа. Теперь в MS SQL.



Теперь число 42244 - это 30 августа! Почему? Ведь обе системы ведут отсчёт от 01.01.1900. Сразу оговорюсь, что совпадать они не обязаны, поскольку MS SQL не "Офис". Одни сутки находим сразу из документации. Оказывается, что Access ведёт отсчёт, начиная от 1, а MS SQL от 0. А где ещё одни сутки? Похоже проблема с учётом "супервисокосных" лет. Так и есть.


Смотри строку три, дата 29.02.1900. Но такой даты в истории нет! В этом можно убедиться, если "отмотать" системный календарь.


Таким образом, разница в представлении времени (в пределах, используемых в АС-Библиотека-3) в виде числа, между Access и MS SQL составляет ровно двое суток.
Теперь главный вопрос - где эта особенность может проявиться? В обычной работе модулей АС-3 после многолетней эксплуатации под MS SQL "косяков" замечено не было. Похоже, что модули используют встроенные функции преобразования и используют движок базы исключительно как хранилище. Проблемы могут возникнуть, если писать собственные модули для "Статистики". При серьёзном администрировании базы обычно приходится делать SQL запросы. Если база MS SQL, то эту особенность также придётся учитывать.
Ну и напоследок ещё несколько известных мне фактов, связанных со временем.
При всех (насколько мне известно) операциях (выдача, создание записи и т.д.) производимых модулями АС-3 в базе фиксируется время клиента, а не сервера. Так что не забывай вовремя менять батарейки на системной плате. Иначе в базе появится "каша". Неплохо будет настроить сервер времени.

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

IF GetOptionValue( "Provider" ) = "1" THEN
'Access
    Val = " VAL( "
ELSE
    Val = " Convert( INT, "
ENDIF

Следующий 2016 год, как известно високосный. И ровно 29 февраля, при попытке вывести статистику "Распределение читателей" или "Регистрация читателей", появится следующая ошибка


Я просто изменил системную дату для демонстрации. Ошибка происходит во встроенной функции AgeToBirthDate(). У меня есть сомнения насчёт её корректности. Но это ты можешь проверить сам. Выход - вывести статистику на следующий день.

На этом всё. Пиши комментарии (регистрация не требуется) или на почту acbib3@yandex.ru

2 комментария:

  1. Добрый день! Не могли бы вы подсказать вот по какому вопросу. В АС Библиотека при создании новой БД есть возможность выбрать компрессию таблицы с данными. В итоге вместо строки в формате ISO2709, там отображаются иероглифы. Но по объему количество символов гораздо меньше, чем в исходной записи. Так вот вопрос: не знаете ли вы, как заставить серверную часть системы преобразовать данные в нормальный (декомпрессированный) вид? Или не подскажите ли вы какой метод сжатия используется?

    ОтветитьУдалить
  2. Давненько не заглядывал, а тут интересный вопрос. Когда-то готовился "разжать" базу без выгрузки и последующей загрузки без

    сжатия, так как при этом теряются связи. В статье "Переход" я касался этой темы. Потратил немало времени, но оказалось не

    актуально.

    Итак в обратном порядке. Алгоритм сжатия широко известный и доступный в исходном коде (на С). Но открыто публиковать применяемые

    технологии было бы некорректно с моей стороны по отношению к разработчикам АС-Библиотека-3. Тем более, что это ничего не даёт.

    Дело в том что это библиотека (программная) работает с байтовыми буферами в составе других программ (архиваторы, АС-3 и т.д.), а

    они добавляют свои правила форматирования (файлов, БД, и т.д.). Программы, работающие отдельно с байтовыми буферами, мне

    неизвестны. Скорее всего их нет, потому, что не понятно для чего...? Если надумаете писать свой "преобразователь" - дайте почтовый

    адрес, я подскажу алгоритм и кое какие заготовки валяются в архивах.
    Теперь как заставить сервер...
    Сжатием управляет значение CompressedDoc таблицы __Options. Оно формируется при создании БД и потом не меняется.

    Изменить можно только на пустой базе (надо проверять) иначе будет каша. Значение 1 заставляет сервер сжать строку перед

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

    В последних версиях АС-Библиотека-3 по умолчанию сжатие отключено.
    Если есть ещё вопросы - задавайте.

    ОтветитьУдалить