在日常开发中,我们经常需要在 Unix 时间戳和人类可读的日期时间之间来回转换。看日志时遇到 1722758400 想知道是哪一天,写代码时需要把 2026-08-04 10:30:00 转成时间戳 —— 每次都打开浏览器搜"timestamp converter"太麻烦了。
今天用 OpenCode 写一个命令行时间戳转换工具,Go 语言实现,约 100 行代码。功能包括:
-ts 将时间戳转换为日期时间(自动识别 10 位秒 / 13 位毫秒)-d 将日期时间转换为时间戳(支持多种日期格式)技术栈:Go 标准库(time、flag、fmt、strconv)
确保本地安装了 Go(1.18+),然后进入项目目录启动 OpenCode:
go version # 确认 Go 已安装 mkdir tsconv && cd tsconv opencode
我对 OpenCode 说:
> 用 Go 帮我写一个命令行时间戳转换工具,功能包括:
> 1. 默认输出当前 Unix 时间戳(秒和毫秒)
> 2. 支持 -ts 1722758400 将时间戳转为日期时间
> 3. 支持 -d "2026-08-04 10:30:00" 将日期时间转为时间戳
> 4. 自动识别 10 位和 13 位时间戳
> 5. 代码控制在 100 行左右,只用 Go 标准库
OpenCode 分析了需求,选择用 flag 包处理命令行参数,用 time 包处理时间转换,很快生成了骨架代码。
关键要点: 需求描述越具体,OpenCode 生成的代码就越精准。一次把参数名、输入示例、边界情况都说清楚,能减少后续修改轮次。
第一版代码生成后,我发现 13 位毫秒时间戳的转换结果不对。我对 OpenCode 说:
> 13 位毫秒时间戳需要先除以 1000 再传给 time.Unix,同时时区默认用本地时区
OpenCode 立刻理解了问题,在转换前加入了判断逻辑:
var sec int64
if ts > 1e12 {
sec = ts / 1000 // 毫秒 → 秒
} else {
sec = ts
}
t := time.Unix(sec, 0)
关键要点: OpenCode 擅长处理这类"数据预处理"逻辑,你只需要指出问题所在,不用自己写修复代码。
单一日期格式不够灵活。我对 OpenCode 说:
> 日期解析要支持多种格式:2026-08-04 10:30:00、2026-08-04、2026/08/04 10:30:00、ISO 8601
OpenCode 生成了一个格式列表,用循环逐个尝试解析:
var dateFormats = []string{
"2006-01-02 15:04:05",
"2006-01-02",
"2006/01/02 15:04:05",
"2006/01/02",
"2006-01-02T15:04:05",
}
这里有个有意思的细节:Go 的时间格式化用的是一个固定的参考时间 Mon Jan 2 15:04:05 MST 2006,所以写格式时也要用这个特定的日期数字。以前每次都要查文档才能记住,现在直接告诉 OpenCode 需要什么输出格式,它自动生成对应的 layout 字符串。
关键要点: OpenCode 帮你省去了记忆 Go 时间格式特殊写法的成本,你只需要关心"我想解析什么格式"。
最后,我希望输出更完整一些。我对 OpenCode 说:
> 时间戳转日期时,同时显示秒和毫秒时间戳、本地时间、UTC 时间、星期几;日期转时间戳时,额外显示距今多久
OpenCode 补充了 t.UTC() 和 time.Since() 的输出,整个工具的输出变得非常清晰:
输入时间戳(秒): 1722758400 本地时间 : 2026-08-04 16:00:00 UTC 时间 : 2026-08-04 08:00:00 星期 : Tuesday
package main
import (
"flag"
"fmt"
"os"
"strconv"
"strings"
"time"
)
var dateFormats = []string{
"2006-01-02 15:04:05",
"2006-01-02",
"2006/01/02 15:04:05",
"2006/01/02",
"2006-01-02T15:04:05",
}
func main() {
tsFlag := flag.String("ts", "", "将时间戳转换为日期时间")
dateFlag := flag.String("d", "", "将日期时间转换为时间戳")
flag.Parse()
if *tsFlag == "" && *dateFlag == "" {
now := time.Now()
fmt.Printf("当前时间戳(秒) : %d\n", now.Unix())
fmt.Printf("当前时间戳(毫秒): %d\n", now.UnixMilli())
fmt.Printf("当前时间(本地) : %s\n", now.Format("2006-01-02 15:04:05"))
fmt.Printf("当前时间(UTC) : %s\n", now.UTC().Format("2006-01-02 15:04:05"))
return
}
if *tsFlag != "" {
ts, err := strconv.ParseInt(strings.TrimSpace(*tsFlag), 10, 64)
if err != nil {
fmt.Fprintf(os.Stderr, "错误:无效的时间戳 \"%s\"\n", *tsFlag)
os.Exit(1)
}
var sec int64
var label string
if ts > 1e12 {
sec = ts / 1000
label = "毫秒"
} else {
sec = ts
label = "秒"
}
t := time.Unix(sec, 0)
fmt.Printf("输入时间戳(%s): %d\n", label, ts)
fmt.Printf("本地时间 : %s\n", t.Format("2006-01-02 15:04:05"))
fmt.Printf("UTC 时间 : %s\n", t.UTC().Format("2006-01-02 15:04:05"))
fmt.Printf("星期 : %s\n", t.Weekday())
return
}
if *dateFlag != "" {
for _, format := range dateFormats {
t, err := time.ParseInLocation(format, strings.TrimSpace(*dateFlag), time.Local)
if err == nil {
fmt.Printf("输入日期 : %s\n", *dateFlag)
fmt.Printf("时间戳(秒) : %d\n", t.Unix())
fmt.Printf("时间戳(毫秒) : %d\n", t.UnixMilli())
fmt.Printf("星期 : %s\n", t.Weekday())
fmt.Printf("距今已过 : %s\n", time.Since(t).Round(time.Second))
return
}
}
fmt.Fprintf(os.Stderr, "错误:无法解析日期 \"%s\"\n", *dateFlag)
fmt.Fprintf(os.Stderr, "支持的格式:\n")
for _, f := range dateFormats {
fmt.Fprintf(os.Stderr, " %s\n", f)
}
os.Exit(1)
}
}
整个开发过程只用了约 3 分钟,我输入了 4 条自然语言指令,就得到了一个完整可用的命令行工具。编译运行:
go build -o tsconv main.go ./tsconv # 显示当前时间戳 ./tsconv -ts 1722758400 # 时间戳 → 日期 ./tsconv -d "2026-08-04 10:30:00" # 日期 → 时间戳
对比传统开发方式:传统开发需要查 Go 时间格式文档、处理字符串解析、测试各种边界情况,至少 20-30 分钟。用 OpenCode 把精力花在"描述清楚需求"上,而不是花在"记住 API 拼写"上。特别是 Go 那个 2006-01-02 15:04:05 的魔幻时间格式,以前每次都要搜文档,现在直接告诉 OpenCode 就行。