#database #arrow # Time - **定义** ```fbs table Time { unit: TimeUnit = MILLISECOND; bitWidth: int = 32; } ``` - **含义** - 自午夜开始流逝的时间(**一天内**,最大值小于24小时) - 例如单位为秒的话,合法的值区间为 $\large [0,\ 864000=24 \times 60 \times 60)$; - 如果单位为毫秒的话,最多到 86400000 <br> - **支持两种 bitWidth** - **32位**:此时,单位 (unit) 可以是 SECOND 和 MILLISECOND - **64位**:此时,单位可以是 MIRCOSECOND 和 NANOSECOND <br> -------- <br> ## Timestamp - **定义** ```fbs table Timestamp { unit: TimeUnit; timezone: string; } ``` - **含义** - Timestamp 的值存储为一个 64 位有符号整型,代表从某个 fixed epoch 作为起点所经历的时间, 单位为:seconds、milliseconds、microseconds 或者 nanoseconds - 可以指定时区,时区格式为 timezone database(如 "America/New_York")或者 offset形式("+07:30") - 不支持闰秒 <br> - **带有时区的 Timestamp** - 如果一个 Timestamp column 的 timezone 非空,它的 epoch 就是 **UTC** 1970-01-01 00:00:00,**忽略** Timestamp 自己的时区(这个时区**只代表了如何展示**) - 因此,带有时区的 Timestamps 之间可以直接按值进行比较,因为它们共享一个相同的参考点(Unix epoch) <br> - **不带时区的 Timestamp** - 它的 epoch 是 1970-01-01 00:00:00,但是 timezone 是**未知**的 - 因此,不带时区的 timestamp values 无法解释为物理时间点,只能作为 **wall clock time** - 例如值为 0 的无时区 timestamp,对应一个未知时区的 "January 1st 1970, 00h00 " - 无时区的 timestamp values **不能**比较和排序,它们可能有着不同的参考点。 <br> - **更改时区** - 如果 Timestamp类型定义里带有时区,则更改时区只需要操作元数据,不用改动 timestamp 的值。 - 如果没有时区,将它更改为一个非空时区,就需要考虑目标语义。 - 一种可能是将原始值解释为相对于目标时区,然后再调整为相对 UTC epoch。 <br> - **外部库如何编码数据** - **instant**:代表时间上的物理点,没有相对时区。可以使用 UTC 时区的 Timestamp 进行编码 - **zoned date-time**:代表时间上的物理点加上时区。编码使用相同时区的 Timestamp 类型,value要相对于 UTC epoch - **offset date-time**:如 "+03:00",类似 zoned date-time <br> - **naive datetime**: - 一些库也称为 local date-time,表示一个 wall clock time + 一个 calendar date, - **没有表明**如何映射到物理时间点。需要小心处理,因为缺少这些信息,加上夏令时可能使一些值存在歧义或者不存在。 - 可以存储为一个 struct(含有 Date + Time 字段) - 也可以编码为无时区的 Timestamp 类型,value 计算需要假设 date time 是 UTC 的。 > 如 “January 1st 1970, 00h00” 编码为 Timestamp 时 value 为 0. ----------------- # Date - **定义** ```fbs enum DateUnit: short { DAY, MILLISECOND } table Date { unit: DateUnit = MILLISECOND; } ``` - **含义** - 表示自 UNIX epoch (1970-01-01) 开始流逝的时间 - 两个单位: - **Milliseconds**:值存储为 64位整型,表示自 UNIX epoch 之后过了多少毫秒,值可以被 86400000 **整除** - **Days**:值存储为 32位整型,表示自 UNIX epoch 之后过了多少天 --------- ## Decimal - **定义** ```fbs table Decimal { /// Total number of decimal digits precision: int; /// Number of digits after the decimal point "." scale: int; bitWidth: int = 128; } ``` - **含义** 存储精确的数值数据: - **precision**:代表总的数字位数(十进制) - **scale**:表示小数点后的位数 - 底层存储为 128位 / 256 位整型 > 如 `DECIMAL(5,2)`, 可以存储范围为 $-999.99$ 到 $999.99$ 的数字 - **Arrow使用** - 从十进制字符串解析:`arrow_cast::parse::parse_decimal()` - 从 i128 中还原为字符串:`arrow::datatypes::Decimal128Type::format_decimal()` - 128类型最多支持到38位(precision),小于 2^127 的位数