golang gin框架进行时间运算之解决orm时间与时间运算——附源码

问题: 进行数据库时间对比。字段有datetime类型,有int类型(表示分钟)。需要判断是否超时

越转出现问题越多。

索性直接使用函数。

分析:

time 结构体为

type Time struct {
    wall unit64     //表示距离公元1年1月1日00:00:00UTC的秒数
    ext  int64      //表示纳秒
    loc  *Location  //代表时区,主要处理偏移量。因为不同的时区,对应的时间不一样
}

那我查询出来的mysql字段,有datetime类型,有int
所以这里,最好的方法其实不是像php那样进行转换,timestamp

而是直接使用 time 函数

time 函数解决方案演示

代码部分截图

m, _ := time.ParseDuration(fmt.Sprintf("%dm", testInfo.CurrentLimitMaxTime))
now := time.Now()

// 如果 当前时间 >= 相加的时间   超时
if now.Sub(time.Time(testInfo.PickTime).Add(m)) >= 0 {

}

time 函数的使用

官方文档函数列表: docscn.studygolang.com/pkg/time/

可以自行查看使用哈。
golang 进行时间运算,尽量使用time函数的方法,别转来转去。

orm time 的封装

参考文档代码链接: www.cnblogs.com/Chaser-Eagle/p/131...

ormtime.go


package util

import (
    "database/sql/driver"
    "encoding/json"
    "fmt"
    "time"
)

const timeFormat = "2006-01-02 15:04:05"

type MyTime time.Time

func (this *MyTime) UnmarshalJSON(data []byte) (err error) {
    now, err := time.ParseInLocation(`"`+timeFormat+`"`, string(data), time.Local)
    *this = MyTime(now)
    return
}

func (this MyTime) MarshalJSON() ([]byte, error) {
    tt := time.Time(this)
    if tt.IsZero() {
        emptyStr, _ := json.Marshal("")
        return emptyStr, nil
    }
    b := make([]byte, 0, len(timeFormat)+2)
    b = append(b, '"')
    b = tt.AppendFormat(b, timeFormat)
    b = append(b, '"')
    return b, nil
}

func (this MyTime) Value() (driver.Value, error) {
    var zeroTime time.Time
    tt := time.Time(this)
    if tt.UnixNano() == zeroTime.UnixNano() {
        return nil, nil
    }
    return tt, nil
}

func (this *MyTime) Scan(v interface{}) error {
    value, ok := v.(time.Time)
    if ok {
        *this = MyTime(value)
        return nil
    }
    return fmt.Errorf("can not convert %v to timestamp", v)
}

func (this MyTime) IsZero() bool {
    tt := time.Time(this)
    if tt.IsZero() {
        return true
    }
    return false
}

func (this MyTime) String() string {
    tt := time.Time(this)
    return tt.String()
}

func (this MyTime) Format() string {
    tt := time.Time(this)
    return tt.Format(timeFormat)
}

func (this MyTime) After(t MyTime) bool {
    tt := time.Time(this)
    return tt.After(time.Time(t))
}

func (this MyTime) Before(t MyTime) bool {
    tt := time.Time(this)
    return tt.Before(time.Time(t))
}

func (this MyTime) Parse(t string) (MyTime, error) {
    tt, err := time.Parse(timeFormat, t)
    return MyTime(tt), err
}

调用方法:在 orm声明中:

`type TestDao struct{`

`Id    uint    `gorm:"primary_key,AUTO_INCREMENT" json:"id"``

`CreatedAt  MyTime `json:"-"``

`UpdatedAt  MyTime `json:"update_at"``

`DeletedAt  *MyTime `json:"-"``

`}`

实现原理

其实现方式其实是通过在save变更时,通过callback功能,将其定义为当前时间。文章可参考 传送门

这样你就可以通过自定义的LocalTime来控制时间格式。

弊端与建议

因为在程序运行时,createAt这类字段的类型还是 LocalTime,所以如果你想自己给其复制,是不太容易做到的。

例如,你想在程序运行时改一下其createAt的时间。你做不到! 因为它的类型是LocalTime,而你的时间要么是时间戳,要么是一个字符串,类型不匹配。。。是不是很尴尬???

所以建议这类保留字段还是不要在程序运行时去修改。只用它作为记录或标识即可。如果真的需要更改时间,还是自己维护字段的内容吧。例如用int存时间戳或string存字符串。然后每次变更时,去修改它的值。

当然也可以将这工作自己封装成一个callback函数,这样你就能够随意控制这个字段了。可参考上文传送门中的内容。

所以,想吐槽的是,go orm对时间格式化的这种实现方式,太不人性化了!

本作品采用《CC 协议》,转载必须注明作者和本文链接
嗨,我是波波。曾经创业,有收获也有损失。我积累了丰富教学与编程经验,期待和你互动和进步! 公众号:上海PHP自学中心 付费知识星球:破解面试:程序员的求职导师
讨论数量: 1

我数据库存的是日期时间戳,char类型。获取日期时间戳用的是统一时间函数。

// 获取日期时间戳,s func GetTimeDate(_format string) string { // 时区 timeZone, _ := time.LoadLocation(ServerInfo["timezone"]) //timeZone := time.FixedZone("CST", 8*3600) // 东八区

timer := time.Now().In(timeZone)

var year int = timer.Year()
var month int = int(timer.Month())
var day int = timer.Day()
var hour int = timer.Hour()
var minute int = timer.Minute()
var second int = timer.Second()

var _year string
var _month string
var _day string
var _hour string
var _minute string
var _second string

_year = IntToString(year)
if month < 10 {
    _month = IntToString(month)
    _month = "0" + _month
}else {
    _month = IntToString(month)
}
if day < 10 {
    _day = IntToString(day)
    _day = "0" + _day
}else {
    _day = IntToString(day)
}
if hour < 10 {
    _hour = IntToString(hour)
    _hour = "0" + _hour
}else {
    _hour = IntToString(hour)
}
if minute < 10 {
    _minute = IntToString(minute)
    _minute = "0" + _minute
}else {
    _minute = IntToString(minute)
}
if second < 10 {
    _second = IntToString(second)
    _second = "0" + _second
}else {
    _second = IntToString(second)
}

_year1 := IntToString(year)
_month1 := IntToString(month)
_day1 := IntToString(day)
_hour1 := IntToString(hour)
_minute1 := IntToString(minute)
_second1 := IntToString(second)

var _date string

switch _format {
case "YmdHis":
    _date = _year + "" + _month + "" + _day + "" + _hour + "" + _minute + "" + _second
    break
case "Y-m-d H:i:s":
    _date = _year + "-" + _month + "-" + _day + " " + _hour + ":" + _minute + ":" + _second
    break
case "y-m-d h:i:s":
    _date = _year1 + "-" + _month1 + "-" + _day1 + " " + _hour1 + ":" + _minute1 + ":" + _second1
    break
case "Y-m-d":
    _date = _year1 + "-" + _month + "-" + _day
    break
case "H:i:s":
    _date = _hour + ":" + _minute + ":" + _second
    break
default:
    _date = _year + "" + _month + "" + _day + "" + _hour + "" + _minute + "" + _second
    break
}

return _date

}

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
司机 @ 欣昊玉
文章
273
粉丝
339
喜欢
558
收藏
1106
排名:64
访问:12.2 万
私信
所有博文
社区赞助商