timer/time.go

130 lines
2.7 KiB
Go
Raw Normal View History

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() }