Golang實現(xiàn)自定義時間結(jié)構(gòu)體并支持Json&Gorm
前言
因為時區(qū)等問題,很多項目需要自定義時區(qū)和時間格式。還有需要自定義輸出顯示。
方案
代碼
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" //月,不帶先導(dǎo)零
const FDay = "02" //日
const FDayNoZero = "2" //日,不帶先導(dǎo)零
const FHour = "15" // 小時,24小時格式
const FMinute = "04" // 分鐘
const FSecond = "05" // 秒
// 1. 創(chuàng)建 time.Time 類型的副本 XTime;
type MyTime struct {
time.Time
}
// 2. 為 MyTime 重寫 MarshaJSON 方法,在此方法中實現(xiàn)自定義格式的轉(zhuǎn)換;
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 實現(xiàn) Value 方法,寫入數(shù)據(jù)庫時會調(diào)用該方法將自定義時間類型轉(zhuǎn)換并寫入數(shù)據(jù)庫;
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 實現(xiàn) Scan 方法,讀取數(shù)據(jù)庫時會調(diào)用該方法將時間數(shù)據(jù)轉(zhuǎn)換成自定義時間類型;
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
}
//解析默認(rèn)格式
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 關(guān)鍵點:
- 實現(xiàn) MarshalJSON 方法
- 實現(xiàn) UnmarshalJSON 方法
- 實現(xiàn) Value 方法
Gorm關(guān)鍵點:
- 實現(xiàn) Scan 方法
- 實現(xiàn) String 方法
到此這篇關(guān)于Golang實現(xiàn)自定義時間結(jié)構(gòu)體并支持Json&Gorm的文章就介紹到這了,更多相關(guān)Go自定義時間結(jié)構(gòu)體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
7分鐘讀懂Go的臨時對象池pool以及其應(yīng)用場景
這篇文章主要給大家介紹了關(guān)于如何通過7分鐘讀懂Go的臨時對象池pool以及其應(yīng)用場景的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或使用Go具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧2018-11-11
GO將mysql?中?decimal?數(shù)據(jù)類型映射到?protobuf的操作方法
這篇文章主要介紹了go如何優(yōu)雅地將?mysql?中?decimal?數(shù)據(jù)類型映射到?protobuf,本文主要展示一下在 protobuf中 float與double的一個區(qū)別,結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2022-09-09
通過Golang實現(xiàn)linux命令ls命令(命令行工具構(gòu)建)
這篇文章主要為大家詳細介紹了如何通過Golang實現(xiàn)一個linux命令ls命令(命令行工具構(gòu)建),文中的示例代碼講解詳細,具有一定的學(xué)習(xí)價值,感興趣的可以了解一下2023-01-01
Go語言基于viper實現(xiàn)apollo多實例快速
viper是適用于go應(yīng)用程序的配置解決方案,這款配置管理神器,支持多種類型、開箱即用、極易上手。本文主要介紹了如何基于viper實現(xiàn)apollo多實例快速接入,感興趣的可以了解一下2023-01-01

