参考书籍《Go语言编程之旅》
首先看一下目录结构
// /cmd/time.go
package cmd
import (
"github.com/spf13/cobra"
"log"
"strconv"
"strings"
"test/internal/timer"
"time"
)
var (
calculateTime string
duration string
timeCmd = &cobra.Command{
Use: "time",
//显示在主命令里面的help
Short: "时间格式处理",
//显示在子命令里面的help
Long: "时间格式处理",
Run: func(cmd *cobra.Command, args []string) {
},
}
nowTimeCmd = &cobra.Command{
Use: "now",
Short: "获取当前时间",
Long: "获取当前时间",
Run: func(cmd *cobra.Command, args []string) {
nowTime := timer.GetNowTime()
//format 按照既定的格式初始化
//unix返回unix时间 即时间戳 该值为UTC 1970年1月1日起经过的秒数
//如果要用其他的时间格式,可以用内部定义的格式
/*
const (
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano = "Jan _2 15:04:05.000000000"
)
*/
log.Printf("输出结果 %s ,%d",nowTime.Format("2006-01-02 15:04:05"),nowTime.Unix())
},
}
calculateTimeCmd = &cobra.Command{
Use: "calc",
Short: "计算所需时间",
Long: "计算所需时间",
Run: func(cmd *cobra.Command, args []string) {
//在这段代码中 展示了三种常用的时间格式处理,分别是 时间戳 2006-01-02 年月日 和2006-01-02 15:04:05 年月日时分秒
var (
currentTimer time.Time
layout = "2006-01-02 15:04:05"
)
if calculateTime == "" {
currentTimer = timer.GetNowTime()
}else {
var err error
//时间处理上 加入了字符串判断 是否又空字符串 如果有的话则按照2006-01-02 15:04:05 没有的话2006-01-02
//这里如果包含空 那么会返回true 那么!true 就是false
if !strings.Contains(calculateTime," ") {
layout = "2006-01-02"
}
//如果按照layout的我们做格式化,出现问题就直接取时间戳
currentTimer,err = time.Parse(layout,calculateTime)
if err != nil {
t,_ := strconv.Atoi(calculateTime)
//取时间戳
currentTimer = time.Unix(int64(t),0)
}
}
calculateTime,err := timer.GetCalculateTime(currentTimer,duration)
if err != nil {
log.Fatalf("time.GetCalcuateTime err : %v\n",err)
}
log.Printf("输出结果: %s %d\n",calculateTime.Format(layout),calculateTime.Unix())
},
}
)
func init() {
timeCmd.AddCommand(nowTimeCmd,calculateTimeCmd)
calculateTimeCmd.Flags().StringVarP(&calculateTime,"calculate","c","",`需要计算的时间,有效单位位置时间戳或已经格式化后的时间`)
calculateTimeCmd.Flags().StringVarP(&duration,"duration","d","",`持续时间,有效单位为ns,us,ms,s,m,h,`)
}
// /internal/timer/time.go
package timer
import (
"time"
)
//对time的now方法进行封装,用于返回当前本地的时间time对象,此处封装主要是为了便于后续对time的进一步统一处理
func GetNowTime() time.Time {
location, _ := time.LoadLocation("Asia/Shanghai")
return time.Now().In(location)
}
//对时间的推算
//ParseDuration 用于从字符串中解析duration 持续时间 ,有效单位ns us ms s m h 在add方法中我们可以传入druation,这样timer就可以得到持续之后的最终的时间
//因为我们不知道传入的值是什么所以没有办法直接用add来做我们需要先解析持续的时间,先用ParseDuration 来处理一下
/*
如果我们知道duration如下 那么我们可以直接用add来处理
GetNowTime().Add(time.Second * 60)
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
*/
func GetCalculateTime(currentTimer time.Time,d string) (time.Time,error) {
duration ,err := time.ParseDuration(d)
if err != nil {
return time.Time{}, err
}
return currentTimer.Add(duration),nil
}
//main.go
package main
import (
"test/cmd"
"log"
)
func main() {
err := cmd.Execute()
if err != nil {
log.Fatalf("cmd.Execute err: %v", err)
}
}
// /cmd/root.go
package cmd
import "github.com/spf13/cobra"
var rootCmd = &cobra.Command{
Use: "test",
Short: "test",
Long: "test",
}
func Execute() error{
return rootCmd.Execute()
}
func init() {
rootCmd.AddCommand(wordCmd,timeCmd)
}
效果展示
至此实现了一个简单的时间工具