OpenCode 实践课:3 分钟用 Go 写出一个命令行时间戳转换工具

项目介绍

在日常开发中,我们经常需要在 Unix 时间戳和人类可读的日期时间之间来回转换。看日志时遇到 1722758400 想知道是哪一天,写代码时需要把 2026-08-04 10:30:00 转成时间戳 —— 每次都打开浏览器搜"timestamp converter"太麻烦了。

今天用 OpenCode 写一个命令行时间戳转换工具,Go 语言实现,约 100 行代码。功能包括:

  • 默认显示当前 Unix 时间戳(秒 + 毫秒)
  • -ts 将时间戳转换为日期时间(自动识别 10 位秒 / 13 位毫秒)
  • -d 将日期时间转换为时间戳(支持多种日期格式)

技术栈:Go 标准库(timeflagfmtstrconv

准备工作

确保本地安装了 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 就行。