1. 概述
1.1 类型名称SJDNP64(Signed Julian Day Number Precision Timestamp 64-bit)
- 全称:有符号儒略日数精度时间戳(64位)。
- 缩写解释:
- S:Signed(有符号,支持负时间)。
- JDN:Julian Day Number(儒略日数,作为桥接标准)。
- P:Precision(可变精度)。
- 64:64位有符号整数(int64_t)。
SJDNP64 是一种紧凑的单一64位有符号整数字段类型,专为存储和计算历史时间而设计。它支持从公元前4713年(Epoch基准)前约100亿年到后约100亿年的广阔范围,最小精度达1秒,同时通过可变精度机制适应不同粒度需求(如现代事件用秒级,宇宙事件用亿年级)。 该类型采用JDN作为内部桥接标准,确保与儒略历(Julian Calendar)和格里高利历(Gregorian Calendar)的无缝转换,支持公元/BC纪年。计算(如加减)基于线性总秒数进行,保留精度表达(误差界)。适用于历史数据库、天文软件、考古应用等场景。1.2 设计目标
- 范围:±1.82×10^10 年(覆盖宇宙年龄138亿年余量)。
- 精度:16级可变(秒 ~ 10亿年),误差界明确。
- 兼容性:JDN桥接,支持负时间(远古事件)。
- 效率:单一字段,位运算解码;大整数计算避免溢出。
- 语言支持:跨平台(C++、Python、JavaScript等)。
1.3 版本信息
- 版本:1.0.0(基于JDN Epoch BC 4713年,支持Signed扩展)。
- 当前日期基准:2025年11月7日(设计时参考)。
- 依赖:标准整数运算;可选天文库(如Astropy)增强转换精度。
2. 规范
2.1 Epoch基准
- 基准时间:公元前4713年1月1日 00:00 UT(儒略历)。
- JDN对应:-0.5(标准JDN 0为同日中午12:00 UT)。
- Unix Epoch偏移:约 -210866803200 秒(1970-01-01 00:00 UT前)。
- 时间表示:总秒数(从Epoch起,可负):
- 正值:Epoch后(未来/现代)。
- 负值:Epoch前(远古,e.g., 100亿年前 ≈ -3.15576×10^17 秒)。
- 公式:总秒数 = (JDN + 0.5) × 86400(中午基准转为午夜)。
2.2 字段结构
- 类型:有符号64位整数(int64_t,范围 -2^63 ~ 2^63-1)。
- 布局(小端序,低位优先):
- Bits 0-3:精度级别 p(无符号,0~15)。
- Bits 4-63:值 v(有符号,-2^59 ~ 2^59-1 ≈ ±5.76×10^17,表示总秒数的“单位数”)。
- 编码/解码:
- 编码:field = (v << 4) | p(算术左移,保持符号)。
- 解码:
- p = field & 0xF。
- v = field >> 4(算术右移,符号扩展)。
- 总秒数 ≈ v * scale(p)(可负;存储时四舍五入)。
- 范围限制:|v| ≤ 2^59 – 1(溢出抛异常)。
- p=0(秒级):±5.76×10^17 秒 ≈ ±1.82×10^10 年。
- 高p:更大范围(e.g., p=15:±1.82×10^26 年)。
2.3 精度级别精度p定义时间单位(scale(p):秒/单位),v为单位倍数。误差界:±scale(p)/2(符号无关)。级别指数增长,便于远古/未来粗粒度存储。| 级别 p | 描述 | scale(p) (秒) | 精度误差 (±半单位) | 最大范围(约,基于2^59 |v|) | |——–|————|————————|————————-|———————————| | 0 | 秒 | 1 | ±0.5秒 | ±1.82 × 10^10 年 | | 1 | 分钟 | 60 | ±30秒 | ±3.05 × 10^11 年 | | 2 | 小时 | 3600 | ±30分钟 | ±5.10 × 10^12 年 | | 3 | 天 | 86400 | ±12小时 | ±1.82 × 10^14 年 | | 4 | 周 | 604800 | ±3.5天 | ±2.60 × 10^15 年 | | 5 | 月 (约) | 2628000 | ±15天 | ±5.52 × 10^16 年 | | 6 | 年 | 31557600 | ±0.5年 | ±5.78 × 10^17 年 | | 7 | 10年 | 315576000 | ±5年 | ±5.78 × 10^18 年 | | 8 | 100年 | 3155760000 | ±50年 | ±5.78 × 10^19 年 | | 9 | 千年 | 31557600000 | ±500年 | ±5.78 × 10^20 年 | | 10 | 万年 | 315576000000 | ±5000年 | ±5.78 × 10^21 年 | | 11 | 10万年 | 3155760000000 | ±5万年 | ±5.78 × 10^22 年 | | 12 | 百万年 | 31557600000000 | ±50万年 | ±5.78 × 10^23 年 | | 13 | 千万年 | 315576000000000 | ±500万年 | ±5.78 × 10^24 年 | | 14 | 亿年 | 3155760000000000 | ±5000万年 | ±5.78 × 10^25 年 | | 15 | 10亿年 | 31557600000000000 | ±5亿年 | ±5.78 × 10^26 年 |
- scale计算:基于年 ≈ 365.25 × 86400 秒。
- 选择指南:现代事件用低p(细精度);远古/宇宙事件用高p(粗精度,节省位)。
2.4 历法转换(JDN桥接)
- 流程:日期 — JDN — 总秒数– SJDNP64。
- 支持:公元/BC(年<0=BC);儒略/格里高利(参数指定)。
- JDN公式:标准整数算法(支持负JD)。
- 格里高利:世纪闰年调整(400年周期)。
- 儒略:每4年闰。
- 精度处理:转换时四舍五入到p级;负时间自然支持(e.g., BC 100亿年 ≈ JDN -1.15×10^11)。
2.5 计算与运算
- 基础:转换为总秒数(大整数处理负/溢出),运算后重编码。
- 加法:total_s = v1 × scale(p1) + v2 × scale(p2);v_res = round(total_s / scale(p_res))。
- 减法:total_s = v1 × scale(p1) – v2 × scale(p2)(支持负结果)。
- p_res选择:默认 min(p1, p2)(保留最细精度);用户可指定。
- 比较/排序:字段值直接线性比较(signed)。
- 精度保留:结果p_res表示新误差界(e.g., 两秒级相加,p_res=0,误差±1秒)。
- 溢出:|v_res| > 2^59-1 时异常(自动升级p_res可缓解)。
3. API 接口(伪代码示例)以下为C++风格伪代码;实际实现需语言适配(e.g., Python类)。
cpp
class SJDNP64 {
public:
static const int64_t MAX_ABS_V = (1LL << 59) - 1;
static const double EPOCH_JD_OFFSET = -0.5;
static const array<long long, 16> SCALES = {1, 60, 3600, /*...*/ 31557600000000000LL};
SJDNP64(int64_t field = 0) : field_(field) {}
// 从字段构造
static SJDNP64 from_field(int64_t field);
// 从日期构造 (年<0=BC)
static SJDNP64 from_date(int year, int month, int day, int precision = 0, bool is_gregorian = true);
// 转日期 (年<0=BC)
tuple<int, int, int> to_date(bool target_gregorian = true) const;
// 解码
pair<int64_t, int> unpack() const; // 返回 v, p
// 总秒数 (可负)
long double to_seconds() const;
// 运算
SJDNP64 operator+(const SJDNP64& other) const;
SJDNP64 operator-(const SJDNP64& other) const;
private:
int64_t field_;
// 内部:date_to_jd, jd_to_gregorian 等函数
};
- Python实现:参考前述完整类(HistoricalTime),替换为SJDNP64。
- 错误处理:OverflowError(范围超)、ValueError(无效p)。
4. 示例
4.1 编码/解码
- 现代事件:2025-11-07 00:00 UT(格里高利,p=0秒级)。
- JDN ≈ 2460984.5,总秒 ≈ 210886803200(正)。
- v ≈ 210886803200,field ≈ 0x1E2B4A8C00000000 | 0。
- 解码:总秒 ≈ 210886803200,日期回推:2025 AD-11-07。
- 远古事件:约100亿年前(BC 9999999999-01-01,儒略,p=14亿年级)。
- JDN ≈ -1.15×10^11,总秒 ≈ -3.15576×10^17(负)。
- v ≈ -1(亿年单位),field ≈ (负v << 4) | 14。
- 解码:总秒 ≈ -3.15576×10^17,误差±5×10^9 年。
4.2 计算示例
- 加法:远古(t1, p=14) + 100亿年偏移(t2, p=14)。
- total_s ≈ 0,结果 v=0, p=14(约Epoch,误差±10^10 年)。
- 减法:2025-11-07 – 1天(p=3天级)= 2025-11-06,p_res=3。
5. 注意事项与限制
- 符号处理:C++用int64_t直接;其他语言模拟符号扩展。
- 精度损失:高p运算可能粗化(e.g., 秒级 + 年级 → 年级)。
- 转换精度:整数JDN误差<1天;生产用Astropy验证远古/闰年。
- 不支持:亚秒、时区/夏令时(可扩展偏移);<Epoch前极值需检查。
- 性能:位运算O(1);大整数运算边缘ケース用__int128/Python int。
- 扩展建议:若需无符号,复位为uint64(仅正时间);添加时分秒参数。
6. 参考与贡献
- 标准:USNO JDN算法(US Naval Observatory)。
- 测试:验证100亿年范围、1582年儒略/格里高利偏移(10天差)。
- 开源:计划GitHub实现,欢迎PR。