Golang实现自定义时间结构体并支持Json&Gorm

 更新时间:2024年03月13日 11:50:50   作者:高山丿流水  
因为时区等问题,很多项目需要自定义时区和时间格式,所以这篇文章主要为大家介绍了Golang如何实现自定义时间结构体并支持Json&Gorm,希望对大家有所帮助

前言

因为时区等问题,很多项目需要自定义时区和时间格式。还有需要自定义输出显示。

方案

代码

package timetool

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

const TimeFormat = "2006-01-02 15:04:05"
const FormatISOTime = "2006-01-02T15:04:05Z"
const DayFormat = "20060102"
const SecondDateFormat = "20060102150405"
const FYear = "2006"     //年
const FMonth = "01"      //月
const FMonthNoZero = "1" //月,不带先导零
const FDay = "02"        //日
const FDayNoZero = "2"   //日,不带先导零
const FHour = "15"       // 小时,24小时格式
const FMinute = "04"     // 分钟
const FSecond = "05"     // 秒

// 1. 创建 time.Time 类型的副本 XTime;
type MyTime struct {
	time.Time
}

// 2. 为 MyTime 重写 MarshaJSON 方法,在此方法中实现自定义格式的转换;
func (t MyTime) MarshalJSON() ([]byte, error) {

	loc := time.FixedZone(pkg.TimeLocal.TimeZone, pkg.TimeLocal.TimeOffset)
	output := fmt.Sprintf("\"%s\"", t.In(loc).Format(TimeFormat))
	return []byte(output), nil
}

// 3. 为 MyTime 实现 Value 方法,写入数据库时会调用该方法将自定义时间类型转换并写入数据库;
func (t MyTime) Value() (driver.Value, error) {
	var zeroTime time.Time
	if t.Time.UnixNano() == zeroTime.UnixNano() {
		return nil, nil
	}
	return t.Time, nil
}

// 4. 为 MyTime 实现 Scan 方法,读取数据库时会调用该方法将时间数据转换成自定义时间类型;
func (t *MyTime) Scan(v interface{}) error {
	value, ok := v.(time.Time)
	if ok {
		*t = MyTime{Time: value}
		return nil
	}
	return fmt.Errorf("can not convert %v to timestamp", v)
}

func (t *MyTime) String() string {
	loc := time.FixedZone(pkg.TimeLocal.TimeZone, pkg.TimeLocal.TimeOffset)
	return t.In(loc).String()
}

func (t *MyTime) GetTime() time.Time {
	loc := time.FixedZone(pkg.TimeLocal.TimeZone, pkg.TimeLocal.TimeOffset)
	return t.In(loc)
}

func (t *MyTime) UnmarshalJSON(data []byte) (err error) {
	// 空值不进行解析
	if len(data) == 2 {
		return
	}

	if string(data) == "null" {
		return
	}

	var now time.Time
	// 指定解析的格式
	if now, err = time.ParseInLocation(TimeFormat, string(data), time.Local); err == nil {
		*t = MyTime{now}
		return
	}
	// 指定解析的格式
	if now, err = time.ParseInLocation('"'+TimeFormat+'"', string(data), time.Local); err == nil {
		*t = MyTime{now}
		return
	}
	//解析默认格式
	if now, err = time.ParseInLocation('"'+time.RFC3339+'"', string(data), time.Local); err == nil {
		*t = MyTime{now}
		return
	}

	return
}

func MyTimeNow() MyTime {
	return MyTime{Time: time.Now()}
}

func NewMyTime(ts ...int64) *MyTime {
	if len(ts) == 0 {
		return &MyTime{Time: time.Now()}
	}
	loc := time.FixedZone(pkg.TimeLocal.TimeZone, pkg.TimeLocal.TimeOffset)
	return &MyTime{
		Time: time.Unix(ts[0], 0).In(loc),
	}
}

注意:

JSON 关键点:

  • 实现 MarshalJSON 方法
  • 实现 UnmarshalJSON 方法
  • 实现 Value 方法

Gorm关键点:

  • 实现 Scan 方法
  • 实现 String 方法

到此这篇关于Golang实现自定义时间结构体并支持Json&Gorm的文章就介绍到这了,更多相关Go自定义时间结构体内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 7分钟读懂Go的临时对象池pool以及其应用场景

    7分钟读懂Go的临时对象池pool以及其应用场景

    这篇文章主要给大家介绍了关于如何通过7分钟读懂Go的临时对象池pool以及其应用场景的相关资料,文中通过示例代码介绍的非常详细,对大家学习或使用Go具有一定的参考学习价值,需要的朋友们下面来一起看看吧
    2018-11-11
  • GO将mysql 中 decimal 数据类型映射到 protobuf的操作方法

    GO将mysql 中 decimal 数据类型映射到 protobuf的操作方法

    这篇文章主要介绍了go如何优雅地将 mysql 中 decimal 数据类型映射到 protobuf,本文主要展示一下在 protobuf中 float与double的一个区别,结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • Go 语言入门之net/url 包

    Go 语言入门之net/url 包

    这篇文章主要介绍了Go 语言入门之net/url 包,文章基于GO语言的相关资料展开 net/url 包的详细内容,具有一定的的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • golang实现给图片加水印

    golang实现给图片加水印

    这篇文章主要为大家详细介绍了Vue3如何利用golang实现给图片加水印,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2023-12-12
  • 通过Golang实现linux命令ls命令(命令行工具构建)

    通过Golang实现linux命令ls命令(命令行工具构建)

    这篇文章主要为大家详细介绍了如何通过Golang实现一个linux命令ls命令(命令行工具构建),文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
    2023-01-01
  • golang判断key是否在map中的代码

    golang判断key是否在map中的代码

    这篇文章主要介绍了golang判断key是否在map中的代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 详解Go语言中单链表的使用

    详解Go语言中单链表的使用

    链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。本文将通过实例为大家详解Go语言中单链表的常见用法,感兴趣的可以了解一下
    2022-08-08
  • 一文详解Golang中new和make的区别

    一文详解Golang中new和make的区别

    在Go语言中,new和make是两个用于创建对象的内建函数。本文将详细介绍new和make的区别,并通过多个方面的分析和代码示例,帮助大家理解它们的使用场景
    2023-05-05
  • Go语言基于viper实现apollo多实例快速

    Go语言基于viper实现apollo多实例快速

    viper是适用于go应用程序的配置解决方案,这款配置管理神器,支持多种类型、开箱即用、极易上手。本文主要介绍了如何基于viper实现apollo多实例快速接入,感兴趣的可以了解一下
    2023-01-01
  • Golang常用包使用介绍

    Golang常用包使用介绍

    标准的Go语言代码库中包含了大量的包,并且在安装Go的时候多数会自动安装到系统中。我们可以在$GOROOT/src/pkg目录中查看这些包。下面简单介绍一些我们开发中常用的包
    2022-09-09

最新评论