← Electerm 博客

在 Electerm 里一眼读懂任意 Unix 时间戳

2026-09-19
时间戳unix 时间终端日志提效技巧

在 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 94668480032503680000(2000-01-01 → 3000-01-01)
13 Unix 毫秒 94668480000032503680000000(同一时间窗口,毫秒单位)

其它一律忽略。也就是说:

  • 1789821105611 → 13 位 → 毫秒 → 2026/9/19 20:31:45
  • 1789821105 → 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())',然后选中它的输出。