• время posix ada GNAT FILETIME Разобрался с конвертацией времени. Как выясняется, в GreyLink DC++ время хранится совсем не в том формате, в котором я подумал, а в FILETIME. Также выяснилось, что и FILETIME в Windows, и time_t в POSIX могут быть как с високосными секундами, так и без. FILETIME, похоже, с високосными секундами не встречается, но тут пишут, что это не исключено. time_t согласно POSIX.1 тоже не должен поддерживать их:
    IEEE Std 1003.1-1988 (``POSIX.1'') legislates that a time_t value of 536457599 shall correspond to "Wed Dec 31 23:59:59 GMT 1986." This effectively implies that POSIX time_t's cannot include leap seconds and, therefore, that the system time must be adjusted as each leap occurs.… но я смотрю на маны posix2time и time2posix и вижу, что совместимость с POSIX где-то может быть сломана в угоду монотонности времени. Всегда надо уточнять, с високосными секундами время или нет, иначе будет разъезжаться на 25 секунд, и с каждым годом всё больше. Вот, допустим, MySQL поддерживает високосные секунды в полях TIMESTAMP, если работать с этими значениями через функцию UNIX_TIMESTAMP. Но как мы уже выяснили, подлинный UNIX time_t не содержит високосных секунд, значит, это может быть только модифицированный. И если вы создаёте значение инструментом, который не вставляет эти секунды, у вас время начнёт разъезжаться. Вот в JavaScript по стандарту временная шкала нелинейная, как и в POSIX.1. Но если POSIX.1 где-то нарушается, то, может быть, и EcmaScript тоже? Давайте проверим:

Replies (2)

  • @OCTAGRAM, > Date.UTC(1986, 11, 31, 23, 59, 59)
    536457599000
    Я вижу, что совпало с POSIX.1. И в Mozilla FireFox тоже совпало. Значит, вы не можете в JavaScript просто поделить время на тысячу и записать это в MySQL. И если OS нарушила POSIX.1, то JavaScript не сможет сходу корректно понимать time_t из неё. Допустим, PHP вызывает time(), он проецируется на системный вызов, результат возвращается в PHP, дальше пишется в базу данных, я такое часто видел. Если OS нарушает POSIX, то из JavaScript это значение на тысячу уже не умножить, а если соблюдает, то в SQL это значение уже не передать в UNIX_TIMESTAMP(). Учитывая, насколько глубоко засели форматы времени, не поддерживающие високосные секунды, не удивительно, что в это время софт так колбасит.

    Я на всякий случай реализовал преобразование и с учётом високосных секунд, и без, чтоб сравнить это с тем, что я вижу в окне GreyLink DC++. Неприятным сюрпризом было то, что поначалу обе даты не отличались. Оказывается, в GNAT поддержку високосных секунд нужно включать ключом gnatbind -y. После того, как включил, даты изменились, но сразу обе, что тоже неправильно. На этот раз это ошибка в реализации стандартной библиотеки. Я пытался сконвертировать, пользуясь стандартным пакетом Ada.Calendar.Arithmetic. Пакет этот весьма небольшой. В этом пакете есть одновременно Difference, разлагающая на дни, обычные секунды и високосные секунды. И есть операции "+" и "-" для дней. И больше в этом пакете нет операций. Но зачем бы они были нужны, если можно пользоваться обычными посекундными "+" и "-" из пакета Ada.Calendar? Наверное, как раз для того, чтобы автоматически перешагивать через високосные секунды. В GNAT на поверку корректно работает только Difference, поэтому пришлось сделать обходной код для этой ошибки. И тогда всё наладилось. Я сравнил даты и пришёл к выводу, что, действительно, атрибут Shared в GreyLink DC++ пишется без поддержки високосных секунд. Что касается FlyLink DC++, я нашёл, как он конвертирует время из формата GreyLink DC++ в свой. Таким образом, это действительно POSIX time_t. Но, может быть, это конвертер ошибается, а файлы, расшаренные самим FlyLink DC++, штампуются как-то иначе? Нашёл, как FlyLink DC++ отображает время. Вызов идёт в gmtime или localtime, а ни MinGW, ни MSVC не нарушают POSIX.1, значит, без високосных секунд.

    Опубликовал библиотеку для конвертации.
  • @OCTAGRAM, судя по всему, документация в MySQL или устарела или всегда была неверной: поведение на 5.7, 5.6 и 5.5 такое как и ожидается без учёта leap second — unix timestamp и TIMESTAMP меняются. Об этом же говорит и комментарий под документацией