文档章节

golang结构体json的时间格式化解决方案

梦朝思夕
 梦朝思夕
发布于 2017/07/15 13:25
字数 810
阅读 421
收藏 1

3 月,跳不动了?>>>

使用了OSC这么久了还没有写一篇博文,真实惭愧!在此写下第一篇。
最近开发项目时候发现一个结构体的Json转换的时间格式问题。 即这种1993-01-01T20:08:23.000000028+08:00 这种表示UTC方法。从我们习惯来说,更喜欢希望的是 1993-01-01 20:08:23这种格式。 重新复现代码如下:


package main

import (
    "time"
    "encoding/json"
)

type Student struct {
    Name string     `json:"name"`
    Brith time.Time `json:"brith"`
}

func main()  {
    stu:=Student{
        Name:"qiangmzsx",
        Brith:time.Date(1993, 1, 1, 20, 8, 23, 28, time.Local),
    }

    b,err:=json.Marshal(stu)
    if err!=nil {
        println(err)
    }

    println(string(b))//{"name":"qiangmzsx","brith":"1993-01-01T20:08:23.000000028+08:00"}
}

遇到这样的问题,那么Golang是如何解决的呢? 有两种解决方案,下面我们一个个来看看。

通过time.Time类型别名

type JsonTime time.Time
// 实现它的json序列化方法
func (this JsonTime) MarshalJSON() ([]byte, error) {
    var stamp = fmt.Sprintf("\"%s\"", time.Time(this).Format("2006-01-02 15:04:05"))
    return []byte(stamp), nil
}
type Student1 struct {
    Name string     `json:"name"`
    Brith JsonTime  `json:"brith"`
}
func main()  {

    stu1:=Student1{
        Name:"qiangmzsx",
        Brith:JsonTime(time.Date(1993, 1, 1, 20, 8, 23, 28, time.Local)),
    }
    b1,err:=json.Marshal(stu1)
    if err!=nil {
        println(err)
    }

    println(string(b1))//{"name":"qiangmzsx","brith":"1993-01-01 20:08:23"}
}

使用结构体组合方式

相较于第一种方式,该方式显得复杂一些,我也不是很推荐使用,就当做是一个扩展教程吧。

type Student2 struct {
    Name string     `json:"name"`
    // 一定要将json的tag设置忽略掉不解析出来
    Brith time.Time  `json:"-"`
}
// 实现它的json序列化方法
func (this Student2) MarshalJSON() ([]byte, error) {
    // 定义一个该结构体的别名
    type AliasStu Student2
    // 定义一个新的结构体
    tmpStudent:= struct {
        AliasStu
        Brith string `json:"brith"`
    }{
        AliasStu:(AliasStu)(this),
        Brith:this.Brith.Format("2006-01-02 15:04:05"),
    }
    return json.Marshal(tmpStudent)
}
func main()  {
    stu2:=Student2{
        Name:"qiangmzsx",
        Brith:time.Date(1993, 1, 1, 20, 8, 23, 28, time.Local),
    }

    b2,err:=json.Marshal(stu2)
    if err!=nil {
        println(err)
    }

    println(string(b2))//{"name":"qiangmzsx","brith":"1993-01-01 20:08:23"}
}

该方法使用了Golang的结构体的组合方式,可以实现OOP的继承,也是体现Golang灵活。

下面把上面的代码组成整体贴出来。


package main

import (
    "time"
    "encoding/json"
    //"fmt"
    "fmt"
)

type Student struct {
    Name string     `json:"name"`
    Brith time.Time `json:"brith"`
}

type JsonTime time.Time
// 实现它的json序列化方法
func (this JsonTime) MarshalJSON() ([]byte, error) {
    var stamp = fmt.Sprintf("\"%s\"", time.Time(this).Format("2006-01-02 15:04:05"))
    return []byte(stamp), nil
}
type Student1 struct {
    Name string     `json:"name"`
    Brith JsonTime  `json:"brith"`
}

type Student2 struct {
    Name string     `json:"name"`
    // 一定要将json的tag设置忽略掉不解析出来
    Brith time.Time  `json:"-"`
}
// 实现它的json序列化方法
func (this Student2) MarshalJSON() ([]byte, error) {
    // 定义一个该结构体的别名
    type AliasStu Student2
    // 定义一个新的结构体
    tmpStudent:= struct {
        AliasStu
        Brith string `json:"brith"`
    }{
        AliasStu:(AliasStu)(this),
        Brith:this.Brith.Format("2006-01-02 15:04:05"),
    }
    return json.Marshal(tmpStudent)
}


func main()  {
    stu:=Student{
        Name:"qiangmzsx",
        Brith:time.Date(1993, 1, 1, 20, 8, 23, 28, time.Local),
    }

    b,err:=json.Marshal(stu)
    if err!=nil {
        println(err)
    }

    println(string(b))//{"name":"qiangmzsx","brith":"1993-01-01T20:08:23.000000028+08:00"}


    println("===================")

    stu1:=Student1{
        Name:"qiangmzsx",
        Brith:JsonTime(time.Date(1993, 1, 1, 20, 8, 23, 28, time.Local)),
    }
    b1,err:=json.Marshal(stu1)
    if err!=nil {
        println(err)
    }

    println(string(b1))//{"name":"qiangmzsx","brith":"1993-01-01 20:08:23"}

    println("===================")
    stu2:=Student2{
        Name:"qiangmzsx",
        Brith:time.Date(1993, 1, 1, 20, 8, 23, 28, time.Local),
    }

    b2,err:=json.Marshal(stu2)
    if err!=nil {
        println(err)
    }

    println(string(b2))//{"name":"qiangmzsx","brith":"1993-01-01 20:08:23"}
}

值得一提的是,对任意struct增加 MarshalJSON ,UnmarshalJSON , String 方法,实现自定义json输出格式与打印方式。

© 著作权归作者所有

梦朝思夕

梦朝思夕

粉丝 112
博文 28
码字总数 56485
作品 2
朝阳
高级程序员
私信 提问
加载中

评论(1)

崔爽
崔爽
使用"-"不还是侵入了原结构体吗?...给整个结构体实现MarshalJSON思路是没错的,但为啥写的这么250?....完全可以无侵入实现
golang结构体json的时间格式化解决方案

最近开发项目时候发现一个结构体的Json转换的时间格式问题。 即这种1993-01-01T20:08:23.000000028+08:00 这种表示UTC方法。从我们习惯来说,更喜欢希望的是 1993-01-01 20:08:23这种格式。 ...

梦朝思夕
2017/07/15
0
0
『Go 语言学习专栏』-- 第四期

大家好,我是谢伟,是一名程序员。 本专栏的主旨是:梳理 Golang 知识,力求从初级水平提升至中级水平。 同时将一些符合人性的编程经验和好的编程方法,分享给大家。 希望对大家有帮助。 本节...

谢小路
2018/05/10
0
0
『Go 语言学习专栏』-- 第八期

大家好,我是谢伟,是一名程序员。 下面的学习是一个系列,力求从初学者的角度学会go 语言,达到中级程序员水平。 这一系列是我的输出总结,同时我还推出了视频版。正在制作过程。 为写出这些...

谢小路
2018/05/15
0
0
『简书API:Golang 处理 json 用法讲解(4):视频版』

大家好,我是谢伟,是一名程序员。 简书API:Jianshu-go 历史文章: 1.『简书API : jianshu 基于 golang (1)』 2.『简书API:jianshu 基于golang -- 用法介绍 (2)』 3. 『简书API:Goque...

谢小路
2018/04/15
0
0
Golang 学习笔记(09)—— json和xml解析

本文为转载,原文:Golang 学习笔记(09)—— json和xml解析 Golang xml package 函数 Marshal Marshal函数返回v的XML编码。 Marshal处理数组或者切片时会序列化每一个元素。Marshal处理指针...

ChainZhang
2018/01/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

HTML使用雪碧图做背景

<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>雪碧图背景图片使用</title> <style> ......

布鲁斯里
7分钟前
8
0
并发编程的艺术07-非阻塞同步演进

前言 不知道大家有没有发现几乎每个专业领域中都充斥着很多抽象的专业名词,如果没有相关的基础知识很难知道这些专业名词是什么意思,就比如说我们的这个标题“粗粒度同步”。川建国听了想骂...

黑帽子技术
8分钟前
9
0
IOS 自动化运维

iOS如何实现自动化打包 iOS自动打包ipa 关于 iOS 批量打包的总结

IT追寻者
9分钟前
7
0
Android 开发技术周报 Issue#274

新闻/News Play Store搜索结果中现显示APP评分、容量和下载量信息 谷歌发布安卓GPU工具:优化手机GPU性能 可OTA更新驱动 Android-x86 9.0-r2 稳定版发布 在PC上运行 Android 教程 抖音包大小...

inferjay
9分钟前
8
0
antd vue 使用setFieldsValue无效的一种可能解决方案

今早遇到的情况是渲染完成之前就对form赋值,因此可以通过setTimeout来解决 解决方案 将代码中的setFieldsValue部分作为函数体嵌入setTimeout,如下: setTimeout(() => { ------setFieldsVa...

SilentSong
16分钟前
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部