在 Electerm 里一眼读懂任意 Unix 时间戳
1789821105611。这是哪一天?是今天早上、上周二,还是 2027 年的某个时刻?除非你这一辈子花了大量时间盯着 epoch 数字看,否则答案并不在你的脑子里。于是你复制这个数字,切到浏览器标签页粘贴,或者在另一个窗格里敲 date -d @...——然后思路就断了。
electerm 把这整段绕路省掉了。在终端里选中这个数字,光标旁边就会弹出一小条提示,显示格式化后的日期时间——在这里是 2026/9/19 20:31:45。点一下,格式化后的字符串就进了剪贴板。
原始 epoch 值的问题
Unix 时间是个绝佳的存储格式,也是个糟糕的阅读格式。它紧凑、无歧义、不带时区、按字符串排序也天然正确。同时,它对人类完全不可读。
所以这些数字在你目之所及的地方到处都是:
- 用
Date.now()或time.time() * 1000打点、而不是输出格式化字符串的应用日志 - 返回
{"created_at":1789821105611}的 JSON 接口响应 docker inspect的输出、Kubernetes 事件、systemd journal 记录- 某个整数列存了时间戳、然后就再没人管过的数据库行
- 构建产物、缓存头、JWT 的
exp声明、S3 对象元数据
以上每一种情况,你都能看见这个数字,只是读不懂它。
选中它,读懂它
整个功能就是一个手势。用鼠标划过这些数字——或者双击这个数字——提示就出现了:
$ tail -n1 app.log
{"ts":1789821105611,"msg":"ok"}
┌──────────────────────┐
│ 2026/9/19 20:31:45 ⧉ │
└──────────┬───────────┘
▼
它不是面板,不是弹窗,也不是另开一个窗口。它就是一条跟着鼠标指针走、悬停在指针上方一点的提示,所以你的视线完全不用离开正在读的那一行。
有三点让它在实际使用中很顺手:
- 只对选中内容做反应。 只有当终端选中的内容是一个纯数字时提示才会出现,一旦取消选中它立刻消失。没有开关,没有需要记住的快捷键。
- 不挡视线。 提示渲染在光标位置上方,永远不会盖住你正在看的那几个数字。
- 移开即消失。 鼠标移开它就没了,不会卡在某个状态里。
究竟什么样的数字会被识别
electerm 不会对任何看起来像数字的字符串都做猜测。它会同时检查长度和合理区间——这正是它不会在端口号、PID、字节数和行号上乱弹提示的原因。
| 位数 | 按什么解释 | 接受区间 |
|---|---|---|
| 9 或 10 | Unix 秒 | 946684800 – 32503680000(2000-01-01 → 3000-01-01) |
| 13 | Unix 毫秒 | 946684800000 – 32503680000000(同一时间窗口,毫秒单位) |
其它一律忽略。也就是说:
1789821105611→ 13 位 → 毫秒 →2026/9/19 20:31:451789821105→ 10 位 → 秒 → 同一时刻,精确到秒178982110561→ 12 位 → 什么都不显示(这是微秒值,electerm 不会假装自己知道)22→ 什么都不显示,那是个端口号
区间检查是这个设计里最安静的一部分。1234567890 是个完全合法的 10 位数,它解出来是 2009 年,所以会触发提示。13 位的 9999999999999 对应 2286 年,同样在窗口内。但纳秒值 1700000000000000000 有 19 位,永远不会给出一个误导性的答案。
复制格式化后的时间
提示弹出后,点击它就会复制格式化后的字符串并关闭提示。文字右侧有一个小小的复制图标作为视觉提示,但整条提示都是可点区域——你不需要精确瞄准那个图标。
有一个实现细节值得知道,因为它是这个点击能生效的根本原因:复制动作绑定在 mousedown 而不是 click 上。在终端上按下鼠标键会清空 DOM 选区,终端随之丢掉自己的选区——那样提示会在 click 事件落地之前就被卸载掉。改用 mousedown 并调用 preventDefault(),选区与焦点都会原封不动地留在原地。
所以整个流程就是:选中 → 阅读 → 点击 → 粘贴。而你拿到的字符串,正是你手算会得到的那一个。
它在哪里最省事
不打断节奏地看日志尾部。 最常见的场景。你在盯一个服务,某一行带着 epoch 时间戳滚过去,你想知道那到底是 30 秒前还是 30 分钟前。
$ tail -n1 app.log | jq -r '.ts'
1789821105611
确认一个过期时间。 JWT 声明、缓存头、会话 cookie、签名 URL——它们都带 epoch 值,也都会逼你做你并不想做的算术。
排查"这件事到底是什么时候发生的"。 把客户端时间戳和服务端时间戳都渲染成人可读的时间之后,对比起来容易得多。
反向生成时间戳。 需要为某个查询造一个时间戳?选中你手上已有的可读时间,用一条 shell 单行命令换算回去:
$ date -d '2026-09-19 20:31:45' +%s%3N
1789821105000
给同事讲清楚。 不用在聊天窗口里解释 1789821105611 是什么意思,选中它、点一下、把可读版本粘过去。
一些值得知道的细节
- 输出格式跟随系统语言环境。 electerm 用你所在 locale 的规则格式化日期。在
zh-CN的机器上你会看到2026/9/19 20:31:45;在en-US上则会看到9/19/2026, 8:31:45 PM。时刻完全相同,呈现方式不同——而这正是你肉眼看时间时想要的效果。 - 必须是完整的选中内容。 校验逻辑是把选区
trim()之后匹配^\d+$。选中{"ts":1789821105611或者1789821105611,都不会匹配,只选中数字本身。 - 秒和毫秒都支持,但不会再往下细分。 微秒和纳秒值(16 位和 19 位)被有意排除在外——因为对任意一个超长数字去猜它用的是什么单位,只会得到自信的错误答案。
- 任何终端会话里都能用。 本地 shell、SSH、Telnet、串口、容器——提示是由终端选区驱动的,跟 shell 无关,所以它并不关心连接的另一端是什么。
- 不会把任何东西发到网络。 换算就是渲染进程里一次
new Date(...)调用。没有网络请求,没有外部服务,没有剪贴板历史。
一个小功能,去掉一点小摩擦
这不是那种会被放到官网首页的功能。它是那种你偶然发现一次、然后一周用上四十次、再换到别的终端里就会格外想念的功能。读时间戳是服务器日常里那些细小、持续、又躲不开的任务之一,而现在它从一个五步操作变成了一个手势。
如果你还没试过:开一个会话,执行 node -e 'console.log(Date.now())',然后选中它的输出。
