Вам не хватает ключевой части картинки: фактических определений структуры даты и времени, которые лежат в Include/datetime.h
. Там также есть важные комментарии. Вот некоторые ключевые выдержки:
/* Fields are packed into successive bytes, each viewed as unsigned and
* big-endian, unless otherwise noted:
*
* byte offset
* 0 year 2 bytes, 1-9999
* 2 month 1 byte, 1-12
* 3 day 1 byte, 1-31
* 4 hour 1 byte, 0-23
* 5 minute 1 byte, 0-59
* 6 second 1 byte, 0-59
* 7 usecond 3 bytes, 0-999999
* 10
*/
...
/* # of bytes for year, month, day, hour, minute, second, and usecond. */
#define _PyDateTime_DATETIME_DATASIZE 10
...
/* The datetime and time types have hashcodes, and an optional tzinfo member,
* present if and only if hastzinfo is true.
*/
#define _PyTZINFO_HEAD \
PyObject_HEAD \
Py_hash_t hashcode; \
char hastzinfo; /* boolean flag */
...
/* All datetime objects are of PyDateTime_DateTimeType, but that can be
* allocated in two ways too, just like for time objects above. In addition,
* the plain date type is a base class for datetime, so it must also have
* a hastzinfo member (although it's unused there).
*/
...
#define _PyDateTime_DATETIMEHEAD \
_PyTZINFO_HEAD \
unsigned char data[_PyDateTime_DATETIME_DATASIZE];
typedef struct
{
_PyDateTime_DATETIMEHEAD
} _PyDateTime_BaseDateTime; /* hastzinfo false */
typedef struct
{
_PyDateTime_DATETIMEHEAD
unsigned char fold;
PyObject *tzinfo;
} PyDateTime_DateTime; /* hastzinfo true */
Счетчик 48 байт, который вы видите, разбивается следующим образом:
- 8-байтовый refcount
- 8-байтовый указатель типа
- 8-байтовый кэшированный хеш
- 1-байтовый флаг "hastzinfo"
- 7-байтовое заполнение
- 10-байтовая ручная упаковка
char[10]
, содержащая данные даты и времени
- 6-байтовое заполнение
Это, конечно, все детали реализации. Он может отличаться в другой реализации Python, или в другой версии CPython, или в 32-разрядной сборке CPython, или в сборке отладки CPython (в PyObject_HEAD есть дополнительные вещи, когда CPython компилируется с определенным Py_TRACE_REFS).