Как дата кодируется/хранится в MySQL?

Мне нужно разобрать дату из необработанных байтов, которые я получаю из базы данных для своего приложения на С++. Я узнал, что дата в MySQL составляет 4 байта, а последние два - это месяц и день соответственно. Но первые два байта странным образом кодируют год, поэтому, если дата 2002-08-30, содержимое будет 210, 15, 8, 31. Если дата 1996-12-22, дата будет храниться как 204. , 15, 12, 22. Очевидно, что первый байт не может быть больше 255, поэтому я проверил 2047 год — это 255, 15, и 2048 — это 128, 16.

Сначала я подумал, что ключ в бинарных операциях, но не совсем понял логику:

2047: 0111 1111 1111
255:  0000 1111 1111
15:   0000 0000 1111

2048: 1000 0000 0000
128:  0000 1000 0000
16:   0000 0001 0000

Есть идеи?

🤔 А знаете ли вы, что...
Язык C++ имеет возможность работы с файлами и потоками данных.


79
3

Ответы:

Решено

Судя по тому, что вы предоставили, похоже, что N1 - 128 + N2 * 128.


Кажется, что логика кодирования заключается в том, чтобы стереть старший бит первого числа и записать из этого стертого бита второе число вот так:

2002 from 210 and 15:

1101 0010 -> _101 0010;
0000 1111 + _101 0010 -> 0111 1101 0010

2048 from 128 and 16:

1000 0000 -> _000 0000
0001 0000 + _000 0000 -> 1000 0000 0000

Какая версия???

DATETIMEраньше был закодирован в упакованном десятичном виде (8 байт). Но когда были добавлены дробные секунды, формат изменился на что-то вроде

  • Индикация длины (1 байт)
  • INT UNSIGNED для секунд с 1970 года (4 байта)
  • доли секунды (0-3 байта)

DATE хранится как MEDIUMINT UNSIGNED (3 байта) как дни с 00:00-00-00 (или что-то в этом роде).

Как вы получили «сырые байты»? Нет никакой функции, которая позволила бы вам это сделать. Select HEX (some-date) сначала преобразуется в строку (например, «2022-03-22»), а затем берет ее шестнадцатеричный код. Это дает вам 323032322D30332D3232.