Solving the problem of time operation in golang gin framework orm time and time operation -- with source code

Posted by Phrank on Thu, 03 Mar 2022 21:07:36 +0100

Question: compare the database time. The field has datetime type and int type (representing minutes). It is necessary to judge whether the timeout occurs

The more you turn, the more problems you have.

Simply use functions directly.


The time structure is

type Time struct {
    wall unit64     //Indicates the number of seconds from 00:00:00 UTC on January 1, A.D
    ext  int64      //Indicates nanoseconds
    loc  *Location  //Represents the time zone, mainly dealing with offset. Because different time zones correspond to different times

The mysql fields I queried have datetime type and int type
So here, the best way is not to convert like php, timestamp.

Instead, use the time function directly

time function solution demo

Screenshot of code part

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

// If current time > = added time timeout
if now.Sub(time.Time(testInfo.PickTime).Add(m)) >= 0 {


Use of time function

Official document function list:

You can check and use it yourself.

Encapsulation of orm time

Reference document code link:


package util

import (

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)

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

Calling method: in orm declaration:

`type TestDao struct{`

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

`CreatedAt  MyTime `json:"-"``

`UpdatedAt  MyTime `json:"update_at"``

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


Implementation principle

The implementation method is to define the current time through the callback function when saving is changed. The article can be referred to Portal

In this way, you can control the time format through the custom LocalTime.

Disadvantages and suggestions

Because the type of fields such as createAt is still LocalTime when the program is running, it is not easy to copy them yourself.

For example, you want to change the time of createAt when the program is running. You can't! Because its type is LocalTime, and your time is either a timestamp or a string. The type does not match... Isn't it embarrassing???

Therefore, it is recommended that such reserved fields should not be modified when the program is running. Only use it as a record or identification. If you really need to change the time, you'd better maintain the contents of the field yourself. For example, use int to save timestamp or string to save string. Then modify its value every time you change it.

Of course, you can also encapsulate this work into a callback function, so that you can control this field at will. Refer to the portal above.

So, to make complaints about it, go orm is too inhumane to format this time.

Topics: Go