Files
VptPassiveAdapter/model/custom_time.go
Jerry Yan 11f508342d feat(config): 更新配置文件并新增自定义时间类型
- 修改 config.yaml 中的 API 地址、存储配置及设备信息
- 新增 Viid 配置项支持新功能模块
- 在 go.mod 和 go.sum 中更新依赖包版本,引入新的第三方库
- 添加 model/custom_time.go 文件实现自定义时间类型的 JSON 序列化与反序列化
- 调整 DTO 结构体以适配新的配置项
- 升级 OTLP 导出器相关依赖并移除旧的标准输出导出器
- 引入 Gin 框架及相关中间件提升服务性能
- 更新 Protobuf 和 gRPC 相关依赖至最新版本
- 增加 zap 日志库和 lumberjack 日志轮转支持
- 添加 sonic、json-iterator 等高性能 JSON 处理库优化数据解析效率
- 引入 testify 断言库增强测试代码可读性
- 更新 sync 包版本提高并发安全性
- 添加 mock 工具支持单元测试模拟对象
- 引入 validator/v10 实现请求参数校验功能
- 更新 crypto、net、text 等标准库依赖确保安全性和兼容性
- 增加 mimetype 库用于文件类型识别
- 引入 quic-go 支持 HTTP/3 协议通信
- 添加 base64x
2025-11-24 16:12:31 +08:00

105 lines
2.4 KiB
Go

package model
import (
"database/sql/driver"
"encoding/json"
"fmt"
"time"
)
// CustomTime 自定义时间类型,用于JSON序列化为YYYY-MM-DD HH:mm:ss格式
type CustomTime struct {
time.Time
}
// MarshalJSON 自定义JSON序列化
func (ct CustomTime) MarshalJSON() ([]byte, error) {
if ct.Time.IsZero() {
return json.Marshal("")
}
return json.Marshal(ct.Time.Format("2006-01-02 15:04:05"))
}
// UnmarshalJSON 自定义JSON反序列化
// 支持格式:
// 1. 数字时间戳:10位秒级(1732435200)或13位毫秒级(1732435200000)
// 2. 字符串格式:秒级(2024-11-24 12:00:00)或毫秒级(2024-11-24 12:00:00.000)
// 3. 空字符串:转换为零值时间
func (ct *CustomTime) UnmarshalJSON(data []byte) error {
// 1. 尝试解析为数字时间戳
var timestamp int64
if err := json.Unmarshal(data, &timestamp); err == nil {
if timestamp == 0 {
ct.Time = time.Time{}
return nil
}
// 根据位数判断精度:13位为毫秒级,10位为秒级
if timestamp > 9999999999 {
ct.Time = time.UnixMilli(timestamp)
} else {
ct.Time = time.Unix(timestamp, 0)
}
return nil
}
// 2. 解析字符串格式
var str string
if err := json.Unmarshal(data, &str); err != nil {
return err
}
if str == "" {
ct.Time = time.Time{}
return nil
}
// 3. 使用本地时区解析时间,避免时区问题
// 尝试多种格式(按精度从高到低)
formats := []string{
"2006-01-02 15:04:05.000", // 毫秒格式
"2006-01-02 15:04:05", // 秒格式(现有)
}
var lastErr error
for _, format := range formats {
t, err := time.ParseInLocation(format, str, time.Local)
if err == nil {
ct.Time = t
return nil
}
lastErr = err
}
return lastErr
}
// Value 实现driver.Valuer接口,用于写入数据库
func (ct CustomTime) Value() (driver.Value, error) {
if ct.Time.IsZero() {
return nil, nil
}
return ct.Time, nil
}
// Scan 实现sql.Scanner接口,用于从数据库读取
func (ct *CustomTime) Scan(value interface{}) error {
if value == nil {
ct.Time = time.Time{}
return nil
}
if t, ok := value.(time.Time); ok {
ct.Time = t
return nil
}
return fmt.Errorf("无法扫描 %T 到 CustomTime", value)
}
// NewCustomTime 创建一个新的 CustomTime 实例
func NewCustomTime(t time.Time) CustomTime {
return CustomTime{Time: t}
}
// NowCustomTime 返回当前时间的 CustomTime 实例
func NowCustomTime() CustomTime {
return CustomTime{Time: time.Now()}
}