工作中使用golang时,遇到了一个问题。声明的struct含time.Time类型。使用json格式化struct时,time.Time被格式化成”2006-01-02T15:04:05.999999999Z07:00“格式。

代码如下

package jsontest

import (
"encoding/json"
"testing"
"time"
) type Person struct {
Id int64 `json:"id"`
Name string `json:"name"`
Birthday time.Time `json:"birthday"`
} func TestTimeJson(t *testing.T) {
now := time.Now()
t.Log(now)
src := `{"id":5,"name":"xiaoming","birthday":"2016-06-30T16:09:51.692226358+08:00"}`
p := new(Person)
err := json.Unmarshal([]byte(src), p)
if err != nil {
t.Fatal(err)
}
t.Log(p)
t.Log(p.Birthday)
js, _ := json.Marshal(p)
t.Log(string(js))
}

golang的time.Time的默认json格式化格式叫做RFC3339。好像是一种国际标准,被推荐用作json时间的标准格式。但是android端不需要这种,而且不容易解析。

经过google,golang文档等途径,写了一个既能解决问题,又不会对源代码产生影响的解决方案。

先看一下google的解决方案

type Time struct {
time.Time
} // returns time.Now() no matter what!
func (t *Time) UnmarshalJSON(b []byte) error {
// you can now parse b as thoroughly as you want *t = Time{time.Now()}
return nil
} type Config struct {
T Time
} func main() {
c := Config{} json.Unmarshal([]byte(`{"T": "bad-time"}`), &c) fmt.Printf("%+v\n", c)
}

原文:http://stackoverflow.com/questions/25087960/json-unmarshal-time-that-isnt-in-rfc-3339-format

但是这样写会对原有的struct产生影响。在映射数据库时,就不行了。此时,心里一片乌云。。。

后来在看url包时,发现了系统包的一种声明数据类型的方式

type Values map[string][]string

根据这种声明方式,受到了启发,便写了一个自己的方法,如下

type Time time.Time

const (
timeFormart = "2006-01-02 15:04:05"
) func (t *Time) UnmarshalJSON(data []byte) (err error) {
now, err := time.ParseInLocation(`"`+timeFormart+`"`, string(data), time.Local)
*t = Time(now)
return
} func (t Time) MarshalJSON() ([]byte, error) {
b := make([]byte, , len(timeFormart)+)
b = append(b, '"')
b = time.Time(t).AppendFormat(b, timeFormart)
b = append(b, '"')
return b, nil
}

同时,将Person的Birthday的类型改为Time,成功的实现的json格式化与json解析。应用到自己的项目中,不会对原有的数据库映射产生影响。需要转换类型的时候,只需Time.(xx)便可,很方便。

以为到这里便结束了。后面还有一个小坑在等我。

struct默认打印结果是将其成员完全打印出来。如把Person打印出来,便是

&{ xiaoming {  0x6854a0}}

我想要的是时间,{63602870991 0 0x6854a0} 是个什么。后来发现,自己的Time类型相当于继承了time.TIme的成员。没有像java一样继承方法。调用了struct默认打印方式。golang有没有类似于java的toString方法呢。

当然有,而且很简单

func (t Time) String() string {
return time.Time(t).Format(timeFormart)
}

这样,就实现了更改打印输出方式

&{ xiaoming -- ::}

最后,把全部代码贴出

package jsontest

import (
"encoding/json"
"testing"
"time"
) type Time time.Time const (
timeFormart = "2006-01-02 15:04:05"
) func (t *Time) UnmarshalJSON(data []byte) (err error) {
now, err := time.ParseInLocation(`"`+timeFormart+`"`, string(data), time.Local)
*t = Time(now)
return
} func (t Time) MarshalJSON() ([]byte, error) {
b := make([]byte, , len(timeFormart)+)
b = append(b, '"')
b = time.Time(t).AppendFormat(b, timeFormart)
b = append(b, '"')
return b, nil
} func (t Time) String() string {
return time.Time(t).Format(timeFormart)
} type Person struct {
Id int64 `json:"id"`
Name string `json:"name"`
Birthday Time `json:"birthday"`
} func TestTimeJson(t *testing.T) {
now := Time(time.Now())
t.Log(now)
src := `{"id":,"name":"xiaoming","birthday":"2016-06-30 16:09:51"}`
p := new(Person)
err := json.Unmarshal([]byte(src), p)
if err != nil {
t.Fatal(err)
}
t.Log(p)
t.Log(time.Time(p.Birthday))
js, _ := json.Marshal(p)
t.Log(string(js))
}

由此,可以对任意struct增加 UnmarshalJSON , MarshalJSON , String 方法,实现自定义json输出格式与打印方式。

golang 自定义time.Time json输出格式的更多相关文章

  1. golang 自定义json解析

    在实际开发中,经常会遇到需要定制json编解码的情况. 比如,按照指定的格式输出json字符串, 又比如,根据条件决定是否在最后的json字符串中显示或者不显示某些字段. 如果希望自己定义对象的编码和 ...

  2. golang 自定义importpath

    golang 的包导入和其他语言有好多不一样的地方,以下是一个自定义的导入 golang 自定义导入说明 一个官方的说明 比较简单,就不翻译了,主要是说我们可以通过添加meta 数据告诉包如何进行加载 ...

  3. Loadrunner请求自定义的http(json)文件and参数化

    Loadrunner请求自定义的http(json)文件and参数化      研究啦好些天这个东西啦 终于出来答案啦 嘿嘿 给大家分享一下 : 请求自定义的http文件用函数:web_custom_ ...

  4. springmvc 自定义view支持json和jsonp格式数据返回

    1.如果controlloer上用@ResponseBody注解,则用<mvc:message-converter>里面配置的json解析器进行解析 <mvc:annotation- ...

  5. Json解析工具Jackson(使用注解)--jackson框架自定义的一些json解析注解

    Json解析工具Jackson(使用注解)--jackson框架自定义的一些json解析注解 @JsonIgnoreProperties 此注解是类注解,作用是json序列化时将Javabean中的一 ...

  6. golang自定义struct字段标签

    原文链接: https://sosedoff.com/2016/07/16/golang-struct-tags.html struct是golang中最常使用的变量类型之一,几乎每个地方都有使用,从 ...

  7. 自定义响应结构 Json格式转换 工具类

    import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterx ...

  8. 【GoLang】golang HTTP GET/POST JSON的服务端、客户端示例,包含序列化、反序列化

    服务端代码示例: package main import ( "encoding/json" "fmt" "io/ioutil" " ...

  9. 自定义JsonResult处理JSON序列化DateTime类型数据(Ext4.2+ASP.NET MVC 4)

    最近项目中前台页面使用Extjs4.2 ,在后台ASP.NET MVC4返回的DateTime类型的数据错返回的DateTime类型的JsonResult的结果中的值是“\/Date(13784461 ...

随机推荐

  1. cnn,rnn,dnn

    CNN(卷积神经网络).RNN(循环神经网络).DNN(深度神经网络)的内部网络结构有什么区别? https://www.zhihu.com/question/34681168 CNN(卷积神经网络) ...

  2. tesnorflow conv deconv,padding

    1.padding test input = tf.placeholder(tf.float32, shape=(1,2, 2,1)) simpleconv=slim.conv2d(input,1,[ ...

  3. lydsy1013: [JSOI2008]球形空间产生器sphere 高斯消元

    题链:http://www.lydsy.com/JudgeOnline/problem.php?id=1013 1013: [JSOI2008]球形空间产生器sphere 时间限制: 1 Sec  内 ...

  4. forceStopPackage与killBackgroundProcesses方法

    最近了解一键清理功能,需要实现强制关闭进程的功能.下面介绍下killBackgroundProcesses()方法和forceStopPackage()方法. killBackgroundProces ...

  5. Java:EL表达式

    ylbtech-Java:EL表达式 EL(Expression Language) 是为了使JSP写起来更加简单.表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 ...

  6. bzoj3270

    3270: 博物馆 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 474  Solved: 261[Submit][Status][Discuss] ...

  7. Connection: close和Connection: keep-alive有什么区别?

    看到有人问Connection: close和Connection: keep-alive有什么区别?想起以前学习到的一篇文章,今天转载来,大家看看,我也再温故知新下.如果有问题补充的在下面可以扩充下 ...

  8. ssh使用秘钥文件连接提示WARNING: UNPROTECTED PRIVATE KEY FILE!(转载)

    转自:http://www.01happy.com/ssh-unprotected-private-key-file/ 在centos 6.4下使用ssh连接远程主机时,用的是另外一个密钥,需要用-i ...

  9. E20170602-ts

    questionnaire  n. 调查问卷; 调查表;  アンケート不是英语 collection   n. 征收; 收集,采集; 收藏品; 募捐; association   n. 联想; 协会, ...

  10. bzoj 4326: NOIP2015 运输计划【树链剖分+二分+树上差分】

    常数巨大,lg上开o2才能A 首先预处理出运输计划的长度len和lca,然后二分一个长度w,对于长度大于w的运输计划,在树上差分(d[u]+1,d[v]+1,d[lca]-2),然后dfs,找出所有覆 ...