GBase 8s
适配迁移
问答

如何从查询结果的ByteBuf中正确提取出纳秒值呢

发表于2024-09-26 11:34:4599次浏览9个评论

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。

【GBase版本】:

V8.8_AEE_3.0.0_1X4_1_e940cf_RHEL6_x86_64

【操作系统】:

麒麟V10

【CPU】:

x86

【问题描述】*:

数据库中定义了一个字段"updated_at",类型为datetime year to fraction(3)。

其中一行记录的值为"2024-09-24 19:09:01.298"。在查询后,对结果集进行解析时报异常:

java.time.DateTimeException: Invalid value for NanoOfSecond (valid values 0 - 999999999): 1647256576
    at java.base/java.time.temporal.ValueRange.checkValidValue(ValueRange.java:319) ~[na:na]
    at java.base/java.time.temporal.ChronoField.checkValidValue(ChronoField.java:718) ~[na:na]
    at java.base/java.time.LocalTime.of(LocalTime.java:344) ~[na:na]
    at java.base/java.time.LocalDateTime.of(LocalDateTime.java:364) ~[na:na]

通过debug发现年月日时分秒均解析正确,唯独纳秒解析错误,解析逻辑如下:

public LocalDateTime decode(@Nonnull ByteBuf buffer) {
 int size = buffer.readUnsignedByte();

   if (size == 0) {
       return null;
   } else if (size == 4) {
       return LocalDateTime.of(buffer.readUnsignedShort(), // Year
                               buffer.readUnsignedByte(),  // Month
                               buffer.readUnsignedByte(),  // DayOfMonth
                               0,                          // Hour
                               0,                          // Minute
                               0,                          // Second
                               0                           // NanoOfSecond
                              );
   } else if (size == 7) {
       return LocalDateTime.of(buffer.readUnsignedShort(), // Year
                               buffer.readUnsignedByte(),  // Month
                               buffer.readUnsignedByte(),  // DayOfMonth
                               buffer.readUnsignedByte(),  // Hour
                               buffer.readUnsignedByte(),  // Minute
                               buffer.readUnsignedByte(),  // Second
                               0                           // NanoOfSecond
                              );
   } else if (size == 11) {
       return LocalDateTime.of(buffer.readUnsignedShort(),         // Year=2024
                               buffer.readUnsignedByte(),          // Month=9
                               buffer.readUnsignedByte(),          // DayOfMonth=24
                               buffer.readUnsignedByte(),          // Hour=19
                               buffer.readUnsignedByte(),          // Minute=9
                               buffer.readUnsignedByte(),          // Second=1
                               buffer.readUnsignedByte() * 1000    // NanoOfSecond=1647256576
                              );
   } else {
       log.warn("unknown decoded size: {}", size);
       return null;
   }
}

如何从查询结果的ByteBuf中正确提取出纳秒值呢?

评论

登录后才可以发表评论
用户头像
liaosnet发表于 1年前
buffer.readUnsignedByte() * 1000 // NanoOfSecond=1647256576
按你的代码,这里也是需要按.readUnsignedByte() 读的,然后组合。
第一个Byte取出为 29
第二个Byte取出为 80
就结束了。
GBase用户20757发表于 1年前
@liaosnet:意思是3位的话,实际上只占用2个字节么?如果是精确到5位呢。
用户头像
liaosnet发表于 1年前
@GBase用户20757:1字节- 1,2位
2字节- 3,4位
3字节- 5 位
后面的0按实际需要保留或者移除。
用户头像
liaosnet发表于 1年前
@GBase用户20757:你这size=11,似乎存在内存越界的可能。
GBase用户20757发表于 1年前
@liaosnet:是,估计把后面的字节给读取了。根据decimals的精度值来判断读取多少位可能比较好
用户头像
liaosnet发表于 1年前
@GBase用户20757:根据字段定义的fraction,来读取具体长度吧。
最佳回答
崔哥发表于 9个月前
赞积分,赞积分
GBase用户51882发表于 2个月前
不清楚啊。
zixuwang发表于 2个月前
等答案了啊。