Skip to content
/ aeon Public

Go 最 🦬🔥⌛️ 时间库!零分配内存与 API 设计美学,性能暴打 Carbon!

License

Notifications You must be signed in to change notification settings

baagod/aeon

Repository files navigation

你或许觉得我疯了,没关系,我也这么认为。

记不清是从哪一刻开始了,也许是源于对 time.Time 和现有时间库的不满与愤怒 —— 我产生了一个近乎荒诞的执念:我自己写一个 Go 时间库?

这一切始于那个简陋、甚至可以说是有些 “丑陋” 的前身 thru,我决定对其系统化更新与重构。无数个灵感与想象如烟火般炸裂,才最终让它完成了跨越维度的蜕变。

我将其正式命名为:Aeon。在古老的哲学中,Aeon 代表着 “永恒” 与 “层叠的维度”。

我选择这个名字,是因为它代表了时间更本质的逻辑 —— 时间不是一条细长的直线,它是流动的、是可以被嵌套和穿透的宇宙。

Aeon

Aeon 是一个试图重塑 Go 语言时间操作体验的库。它不只是教你 “拨动时钟”,还教你如何 操控时空结构

📦 安装

go get github.com/baagod/aeon

🧊 核心理念:容器

要掌握 Aeon 时间导航,你只需要理解一个核心概念:容器

即,所有 时间导航 操作,本质上都是在 当前单位的父级容器 中进行 Zero-based (从 0 开始) 寻址。

  • GoYear(5): 不是去公元 5 年,而是在 本年代 这个 父级容器 中,索引 到第 5 年 ➜ ···5
  • GoDecade(2): 索引到 本世纪 第 2 个年代 ➜ ··2·
  • GoCentury(0): 是索引到 本千年 第 0 个世纪 ➜ ·0··

在现实世界中,没有第 0 个世纪,这样设计是为了更简洁和直观表达。例如:GoCentury(1)21··

🧭 时间导航

导航矩阵

Aeon 的 API 设计是完全 正交 的,你只需要记住 4 个动作,就能推导出所有 API。

  • Go.. 全绝对定位 (abs, abs..): GoYear(5) ➜ 本年代第 5 年
  • Add/By.. 全相对偏移 (rel, rel..): AddYear(1) ➜ 明年
  • At.. 先定后移 (abs, rel, rel..): AtYear(5, 1) ➜ 在本年代的第 5 年偏移 1 个月
  • In.. 先移后定 (rel, abs, abs..): InYear(1, 5) ➜ 明年 5 月

提示:

  1. ByAddStart/End 前缀下的别名,它们逻辑完全相同。
  2. Add 系列方法的默认值为 1,其余为 0

时间边界

在上述 4 个动作 加入 Start/End 前缀,能定位到该时间单位的 边界

  • Start.. (归零):将所有下级时间单位归零。如 00:00:00.000..
  • End.. (置满):将所有下级时间单位置满。如 23:59:59.999..

示例:

  • StartYear(5) (对应 Go):本年代第 5 年的 年初 ( 01-01 00:00:00.000.. )。
  • StartByYear(1) (对应 Add):明年 年初
  • StartAtYear(5, 1) (对应 At):本年代第 5 年偏移 1 个月的 月初 ( 01 00:00:00.000.. )。
  • StartInYear(1, 5) (对应 In):明年 5 月初

顶级导航

Aeon 提供了 6 个顶级方法作为进入 “绝对年份” 入口。

规则非常简单:首个 参数永远代表着 绝对年份后续 参数的行为完全遵循 导航矩阵

  1. Go(2025, 2) ➜ 2025-02
  2. At(2025, 2) ➜ 定位到 2025 年后再偏移 2 个月
  3. Start(2025, 2) ➜ 2025-02-01 00:00:00
  4. StartAt(2025, 1) ➜ 定位到 2025 年后再偏移 1 个月的月初
  5. End(2025, 2) ➜ 2025-02-28 23:59:59...
  6. EndAt(2025, 1) ➜ 定位到 2025 年后再偏移 1 个月的月末

级联导航

链式调用?不,是原子操作!GoYear(5, 2, 1) ➜ 2025-02-01。

所有方法均支持 变长参数 向下级联,参数像水流,一行代码即可完成复杂定位

级联序列

Aeon 会根据 入口单位 自动切换 4 种不同的级联序列。

  1. 标准流 Default世纪 ➜ 年代 ➜ 年 ➜ 月 ➜ 日 ➜ 时.. ➜ 纳秒
  2. 季度流 Quarter季度 ➜ 月 (季内) ➜ 日 ➜ 时.. ➜ 纳秒
  3. 月周流 Week周 (月内) ➜ 星期 ➜ 时.. ➜ 纳秒
  4. 年周流 YearWeek年周 ➜ 星期 ➜ 时.. ➜ 纳秒

负数索引

在级联中,负数参数不仅仅是减法,它是 反向索引,代表在 “容器内倒数第 N 个”。

这让你无需关心大月小月或平闰年,直接定位 “尾部”。

实战场景

场景 1:标准流 + 反向寻址 寻找 "2025年,第2个月,最后一天,23点"

// 1. Go(2025): 顶级入口,定位年份
// 2. StartMonth(2): 2月
// 3. 参数 -1: 倒数第一天 (28日)
// 4. 参数 23: 23点
t.Aeon().Go(2025).StartMonth(2, -1, 23)

场景 2:季度流 + 边界置满 寻找 "本年第 3 季度的最后一个月,最后一天"

// 1. EndQuarter(3): 定位到第3季度结束时刻
// 2. 参数 -1: 季度的最后一个月 (9月)
// 3. 参数 -1: 月的最后一天 (30日)
t.EndQuarter(3, -1, -1)

场景 3:年周流 + 精准定位 寻找 "2025年第 10 周的周五,上午 9 点"

// 1. Go(2025): 定位到 2025 年
// 2. StartYearWeek(10, 5, 9): 
//    - YearWeek: 10 (第10周)
//    - Weekday: 5 (周五)
//    - Hour: 9 (9点)
t.Go(2025).StartYearWeek(10, 5, 9)

🛡️ 溢出保护

Aeon 默认拦截非预期的日期溢出,但也赋予你打破规则的权利。

t := aeon.NewDate(2025, 1, 31)

// 默认行为:智能截断
t.GoMonth(2) // -> 2月28日 (自动截断)

// 显式溢出:打破容器限制
t.GoMonth(aeon.Overflow, 2) // -> 3月3日 (2月28 + 3天)

🛠️ 深度技术

Aeon 不仅追求语义的优雅,更追求极致的性能。

  • Zero Alloc: 核心导航逻辑 0 内存分配
  • Bitmask Protocol: 我们将 ISO, Overflow 等配置压缩进了 int 参数的高位,避免了创建配置对象的开销。
  • Nano Precision: 全链路支持纳秒级对齐,End* 方法精准覆盖到 .999999999,确保数据库范围查询不漏数据。

About

Go 最 🦬🔥⌛️ 时间库!零分配内存与 API 设计美学,性能暴打 Carbon!

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages