MySQL Connector C++字段Value的4字节原始数据转日期解析问题
问题解答
1 DATE字段返回4字节的原因
你参考的编码规则是MySQL经典客户端/服务器协议的日期存储规则,而你使用的mysqlx/xdevapi.h是MySQL X DevAPI的接口,底层走的是MySQL X协议,二者编码规则完全不同。X协议的日期编码规则在MySQL官方X DevAPI协议文档中有明确说明,其中DATE类型固定用4字节小端编码,结构如下:
- 第1-2字节:16位小端存储的年份
- 第3字节:月份(取值范围1~12)
- 第4字节:日期(取值范围1~31)
你示例中的1999-03-30对应的4字节编码为0xcf 0x07 0x03 0x1e,和你拿到的raw_bytes长度完全匹配。
2 DATETIME类型的编码规则
你后续将字段修改为DATETIME后,X协议中DATETIME类型固定用7字节小端编码,结构如下:
- 前4字节和DATE类型编码规则完全一致
- 第5字节:小时(取值范围0~23)
- 第6字节:分钟(取值范围0~59)
- 第7字节:秒(取值范围0~59)
你示例中的1999-03-30 00:00:00对应的7字节编码为0xcf 0x07 0x03 0x1e 0x00 0x00 0x00。
3 更简便的日期取值方式
不需要手动解析原始字节,X DevAPI的Value类已经内置了日期类型转换方法:
- 对于DATE字段,直接调用
field_value.get<mysqlx::Date>()获取Date对象,可直接调用getYear()、getMonth()、getDay()方法获取对应值 - 对于DATETIME字段,直接调用
field_value.get<mysqlx::DateTime>()获取DateTime对象,额外可调用getHour()、getMinute()、getSecond()方法获取时间部分的值
对应代码示例如下:
if (field_type == Type::DATE) { Date date = field_value.get<Date>(); cout << field_name << " : " << date.getYear() << "-" << (int)date.getMonth() << "-" << (int)date.getDay() << endl; } else if (field_type == Type::DATETIME) { DateTime dt = field_value.get<DateTime>(); cout << field_name << " : " << dt.getYear() << "-" << (int)dt.getMonth() << "-" << (int)dt.getDay() << " " << (int)dt.getHour() << ":" << (int)dt.getMinute() << ":" << (int)dt.getSecond() << endl; }
内容的提问来源于stack exchange,提问作者Bamaco
相关产品推荐
相关产品推荐

