工作中使用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. 手动脱RLPack壳实战

    作者:Fly2015 吾爱破解论坛培训第一课选修作业练习的第7题. 这个壳没听说过.可是脱起来比較简单.依据ESP定律就可以直达光明,Dump出原来的程序. 老规矩.首先对须要脱壳的程序进行查壳处理. ...

  2. php(cli模式)执行文件传递参数

    php -f index.php hello test 2314 shell命令执行php文件不像http那样通过GET方式传参 同样php文件获取的时候也不能用$_GET方法了 而是通过$argv[ ...

  3. php与国付宝对接过程吐槽

    最近.我们在打造全国第一家互联网+风险管理平台(避险谷)时.须要与第三方支付平台"国付宝"进行在线交易对接. 之前对接过支付宝 .感觉还非常easy,拿到国付宝的接口文档.我晕啊. ...

  4. android.app.Fragment与android.support.v4.app.Fragment不一致

    在看法中用到的Fragment在类型转换的时候非常easy出现这样的问题: 对照代码: class MyFragmentPagerAdapter extends FragmentPagerAdapte ...

  5. python generator iterator和iterable object

    1 iterable object list.dict.set.tuple.file(在每行上iterate)等都是iterable object,但是它们不是iterator.但是它们可以转换成it ...

  6. Android合并两个APP的详细做法(掌握)

    有时候因公司需求,要求合并两个APP 使用里面的功能. 平台:Studio 小白鼠:二维码扫描 和自己项目 详细步骤: /**  * 1.将解压后的android/assets目录复制到项目中的mai ...

  7. SpringMVC 运行过程

    加入jar包 在web.xml中配置DispatherServlet 加入SpringMVC配置文件 编写处理请求的处理器,并表示为处理器 编写视图 可见的运行流程: 实际的运行流程:

  8. where 1=1影响效率以及having和where的区别

    低效的“WHERE 1=1” 网上有不少人提出过类似的问题:“看到有人写了WHERE 1=1这样的SQL,到底是什么意 思?”. 其实使用这种用法的开发人员一般都是在使用动态组装的SQL. 让我们想像 ...

  9. 服务器端解决ajax跨域问题

    这里描述以Tomcat为Web服务器情况下的解决办法,在Java Web程序的WEB-INF下的web.xml文件中加入如下配置即可. <!--cors filter--> <fil ...

  10. set && muliset

    #include <set> #include <iostream> #include <cstdio> #include <cctype> using ...