130 lines
2.7 KiB
Go
130 lines
2.7 KiB
Go
package time
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"apigo.cc/go/cast"
|
|
)
|
|
|
|
// TimeZone 定义了特定时区上下文下的时间操作
|
|
type TimeZone struct {
|
|
*cast.TimeZone
|
|
}
|
|
|
|
// New 创建一个时区上下文
|
|
func New(loc *time.Location) *TimeZone {
|
|
return &TimeZone{TimeZone: cast.NewTimeZone(loc)}
|
|
}
|
|
|
|
// Parse 将任意类型转换为 time.Time。
|
|
// 转换失败返回当前时间 time.Now()。
|
|
func (tz *TimeZone) Parse(v any) time.Time {
|
|
tm := tz.ParseTime(v)
|
|
if tm.IsZero() {
|
|
return time.Now().In(tz.Location())
|
|
}
|
|
return tm
|
|
}
|
|
|
|
// Parse 将任意类型转换为 time.Time。
|
|
func Parse(v any) time.Time {
|
|
tm := cast.ParseTime(v)
|
|
if tm.IsZero() {
|
|
return time.Now().In(cast.DefaultTimeZone.Location())
|
|
}
|
|
return tm
|
|
}
|
|
|
|
// Format 格式化时间。
|
|
func (tz *TimeZone) Format(layout string, v any) string {
|
|
return tz.FormatTime(layout, v)
|
|
}
|
|
|
|
// Format 格式化时间。
|
|
func Format(layout string, v any) string {
|
|
return cast.FormatTime(layout, v)
|
|
}
|
|
|
|
// Add 时间加减 DSL。
|
|
func (tz *TimeZone) Add(expr string, v any) time.Time {
|
|
return tz.AddTime(expr, v)
|
|
}
|
|
|
|
// Add 时间加减 DSL。
|
|
func Add(expr string, v any) time.Time {
|
|
return cast.AddTime(expr, v)
|
|
}
|
|
|
|
// Timer 计时器
|
|
type Timer struct {
|
|
start time.Time
|
|
last time.Time
|
|
laps []Lap
|
|
pause time.Duration
|
|
}
|
|
|
|
type Lap struct {
|
|
Label string
|
|
Duration time.Duration
|
|
At time.Time
|
|
}
|
|
|
|
// Start 开始计时
|
|
func Start() *Timer {
|
|
now := time.Now()
|
|
return &Timer{start: now, last: now}
|
|
}
|
|
|
|
// Record 记录一段耗时 (Lap),并返回段耗时
|
|
func (t *Timer) Record(label string) time.Duration {
|
|
now := time.Now()
|
|
d := now.Sub(t.last)
|
|
t.last = now
|
|
t.laps = append(t.laps, Lap{Label: label, Duration: d, At: now})
|
|
return d
|
|
}
|
|
|
|
// Pause 暂停记录
|
|
func (t *Timer) Pause(label string) {
|
|
now := time.Now()
|
|
d := now.Sub(t.last)
|
|
t.laps = append(t.laps, Lap{Label: label, Duration: d, At: now})
|
|
t.last = now // 暂时标记下一次开始点
|
|
}
|
|
|
|
// Resume 从暂停中恢复
|
|
func (t *Timer) Resume() {
|
|
t.last = time.Now()
|
|
}
|
|
|
|
// Stop 结束计时,返回总持续时间
|
|
func (t *Timer) Stop() time.Duration {
|
|
return time.Since(t.start)
|
|
}
|
|
|
|
// Summarize 返回所有记录段
|
|
func (t *Timer) Summarize() []Lap {
|
|
return t.laps
|
|
}
|
|
|
|
// Describe 返回格式化后的统计字符串
|
|
func (t *Timer) Describe() string {
|
|
var sb strings.Builder
|
|
total := t.Stop()
|
|
for _, lap := range t.laps {
|
|
sb.WriteString(fmt.Sprintf("[%s] %v; ", lap.Label, lap.Duration))
|
|
}
|
|
sb.WriteString(fmt.Sprintf("Total: %v", total))
|
|
return sb.String()
|
|
}
|
|
|
|
// DescribeDuration 将时长转化为自然语言描述
|
|
func DescribeDuration(d time.Duration) string {
|
|
return cast.DescribeDuration(d)
|
|
}
|
|
|
|
// Now 获取当前时间
|
|
func Now() time.Time { return cast.Now() }
|