#timestamp #arrow #integer #precision #cast

arrow-cast-guess-precision

具有时间戳整数猜测精度的箭头类型转换函数替代方案

4个版本 (破坏性)

0.4.0 2024年1月18日
0.3.0 2024年1月10日
0.2.0 2023年11月30日
0.1.0 2023年11月30日

#1620 in 算法

MIT 协议

21KB
286

arrow-cast-guess-precision

使用精度猜测选项将整数转换为时间戳。

只需将 arrow::compute::cast 替换为 arrow_cast_guess_precision::cast,即可完成所有操作。

use arrow::{
    array::{Int64Array, TimestampNanosecondArray},
    datatypes::{DataType, TimeUnit}
};

let data = vec![1701325744956, 1701325744956];
let array = Int64Array::from(data);
let array = arrow_cast_guess_precision::cast(
    &array,
    &DataType::Timestamp(TimeUnit::Nanosecond, None),
)
.unwrap();
let nanos = array
    .as_any()
    .downcast_ref::<TimestampNanosecondArray>()
    .unwrap();
assert_eq!(nanos.value(0), 1701325744956 * 1000 * 1000);

与官方的 arrow::compute::cast 的区别在于

  • arrow v49 将直接将整数转换为时间戳,但此crate(arrow-cast-guess-precision = "0.3.0")会尝试从值中进行猜测。
  • arrow v48 不支持从整数到时间戳的转换(arrow-cast-guess-precision = "0.2.0")。

猜测方法为

use arrow::datatypes::TimeUnit;

const GUESSING_BOUND_YEARS: i64 = 10000;
const LOWER_BOUND_MILLIS: i64 = 86400 * 365 * GUESSING_BOUND_YEARS;
const LOWER_BOUND_MICROS: i64 = 1000 * 86400 * 365 * GUESSING_BOUND_YEARS;
const LOWER_BOUND_NANOS: i64 = 1000 * 1000 * 86400 * 365 * GUESSING_BOUND_YEARS;

#[inline]
const fn guess_precision(timestamp: i64) -> TimeUnit {
    let timestamp = timestamp.abs();
    if timestamp > LOWER_BOUND_NANOS {
        return TimeUnit::Nanosecond;
    }
    if timestamp > LOWER_BOUND_MICROS {
        return TimeUnit::Microsecond;
    }
    if timestamp > LOWER_BOUND_MILLIS {
        return TimeUnit::Millisecond;
    }
    TimeUnit::Second
}

用户可以在构建时设置 ARROW_CAST_GUESSING_BOUND_YEARS 环境变量来控制猜测范围。以下是根据个别环境值的一个示例列表

下限 上限
100 1970-02-06t12:00:00 2069-12-07T00:00:00
200 1970-03-15t00:00:00 2169-11-13T00:00:00
500 1970-07-02t12:00:00 2469-09-01T00:00:00
1000 1971-01-01T00:00:00 2969-05-03T00:00:00
2000 1972-01-01t00:00:00 3968-09-03T00:00:00
5000 1974-12-31t00:00:00 6966-09-06T00:00:00
10000 1979-12-30t00:00:00 +11963-05-13T00:00:00

我们默认使用 ARROW_CAST_GUESSING_BOUND_YEARS=1000,因为 1000 毫秒是 1 秒,因此下限从 1971-01-01T00:00:00 开始,这是零Unix时间戳之后的一年,而上限足够大(即使是100年也足够)。

arrow::compute::cast 一样,此crate也支持具有特定选项的类型转换,请参阅 CastOptions

许可证:MIT

依赖关系

~8–14MB
~162K SLoC