在日常开发工作中,我们进行会遇到将 struct 序列化 json字符串以及将 json字符串 反序列化为 struct 的场景,大家也对此十分熟悉。

最近工作中,遇到了需要将 struct 序列化 xml字符串以及将 xml字符串 反序列化为 struct 的场景,对于普通类型的字段,比如int、string 等类型,直接使用并没有啥问题。

当遇到 时间类型 时,序列化和反序列化并不是自己想要的格式,这个时候就需要我们自定义时间类型的序列化/反序列化方式。

对于json序列化时间类型,大家可能已经比较熟悉了,一般是自定义一个时间类型或者为struct自定义MarshalJSON()([]byte, error)UnmarshalJSON(b []byte) error方法,这样就可以实现将时间格式化为我们想要的格式了。

其实对于xml来说也是一样的,方式也是上面两种,这里就介绍下自定义时间类型,来实现xml的序列化/反序列化。

代码如下:

package main

import (
"encoding/json"
"encoding/xml"
"fmt"
"strings"
"time"
) const timeLayout = "2006-01-02T15:04:05.000+08:00" var location *time.Location func init() {
location, _ = time.LoadLocation("Asia/Shanghai")
} // XSDDateTime is a type for representing xsd:datetime in Golang
type XSDDateTime struct {
innerTime time.Time
} func CreateXSDDateTime(dt time.Time) XSDDateTime {
return XSDDateTime{
innerTime: dt,
}
} func (xdt XSDDateTime) String() string {
return xdt.innerTime.Format(timeLayout)
} // ToGoTime converts the time to time.Time by checking if a TZ is specified.
// If there is a TZ, that TZ is used, otherwise local TZ is used
func (xdt *XSDDateTime) ToGoTime() time.Time { return time.Date(xdt.innerTime.Year(), xdt.innerTime.Month(), xdt.innerTime.Day(),
xdt.innerTime.Hour(), xdt.innerTime.Minute(), xdt.innerTime.Second(),
xdt.innerTime.Nanosecond(), location)
} func (xdt XSDDateTime) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
value := xdt.innerTime.Format(timeLayout)
attr := xml.Attr{Name: name, Value: value}
return attr, nil
} func (xdt *XSDDateTime) UnmarshalXMLAttr(attr xml.Attr) error {
value := attr.Value
t, err := time.Parse(timeLayout, value)
if err != nil {
return err
}
xdt.innerTime = t
return nil
} func (xdt XSDDateTime) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
formatted := xdt.innerTime.Format(timeLayout)
return e.EncodeElement(formatted, start)
} func (xdt *XSDDateTime) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string
if err := d.DecodeElement(&value, &start); err != nil {
return err
} parsedTime, err := time.Parse(timeLayout, value)
if err != nil {
return err
} xdt.innerTime = parsedTime
return nil
} func (xdt XSDDateTime) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%s"`, xdt.innerTime.Format(timeLayout))), nil
} func (xdt *XSDDateTime) UnmarshalJSON(data []byte) error {
var dt time.Time if err := json.Unmarshal(data, &dt); err != nil {
return err
}
xdt.innerTime = dt
return nil
} type Test struct {
TD XSDDateTime `xml:"TD,attr"`
TD1 *XSDDateTime `xml:"TD1,attr,omitempty"`
T XSDDateTime `xml:"T"`
T1 *XSDDateTime `xml:"T1,omitempty"`
} func main() { // 创建一个 soap.XSDDateTime 类型的实例
xsdDateTime := CreateXSDDateTime(time.Now())
fmt.Println("now -->", time.Now()) t := Test{
TD: xsdDateTime,
T: xsdDateTime,
} // 使用 xml.Marshal 将 soap.XSDDateTime 编组为 XML 数据
xmlData, err := xml.MarshalIndent(t, "", " ")
if err != nil {
fmt.Println("Error marshaling:", err)
return
} // 输出编组后的 XML 数据
fmt.Println(string(xmlData))
fmt.Println(strings.Repeat("-", 10)) //tt := `<Test TD="2023-11-24T10:24:27.129+08:00">
//<T>2023-11-24T18:22:27.129+08:00</T>
//</Test>
//` tt := string(xmlData)
var dddd Test
err = xml.Unmarshal([]byte(tt), &dddd)
fmt.Println(err)
fmt.Printf("Test --> %+v\n", dddd)
fmt.Printf("%v\n", dddd.T.ToGoTime())
fmt.Printf("%v\n", dddd.T.ToGoTime().Format(timeLayout)) }

执行结果:

now --> 2023-11-30 11:00:54.0918059 +0800 CST m=+0.003982301
<Test TD="2023-11-30T11:00:54.091+08:00">
<T>2023-11-30T11:00:54.091+08:00</T>
</Test>
----------
<nil>
t --> {TD:2023-11-30T11:00:54.091+08:00 TD1:<nil> T:2023-11-30T11:00:54.091+08:00 T1:<nil>}
2023-11-30 11:00:54.091 +0800 CST
2023-11-30T11:00:54.091+08:00

Golang中如何自定义时间类型进行xml、json的序列化/反序列化的更多相关文章

  1. Mybatis中使用自定义的类型处理器处理枚举enum类型

    知识点:在使用Mybatis的框架中,使用自定义的类型处理器处理枚举enum类型 应用:利用枚举类,处理字段有限,可以用状态码,代替的字段,本实例,给员工状态字段设置了一个枚举类 状态码,直接赋值给对 ...

  2. Golang中的各种时间操作

    Golang中的各种时间操作 需求 时间格式的转换比较麻烦,自己写了个工具,可以通过工具中的这些方法相互调用转成自己想要的格式,代码如下,后续有新的函数再添加 实现代码 package utils i ...

  3. MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP

    MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP,其中 DATE 类型用于表示日期,但是不会包含时间,格式为 YYYY-MM-DD,而 DATETIME 和 T ...

  4. PHPExcel对于Excel中日期和时间类型的处理

    PHPExcel是一款优秀的处理Excel文件读写的开源PHP Library,能够给我们提供强大的Excel读写能力,本文针对Excel处理过程中关于日期和时间类型的处理进行深入的讨论.PHPExc ...

  5. golang 中string和int类型相互转换

    总结了golang中字符串和各种int类型之间的相互转换方式: string转成int: int, err := strconv.Atoi(string)string转成int64: int64, e ...

  6. MySQL 中的日期时间类型

    日期时间类型中包含以下几种数据类型: DATE TIME DATETIME TIMESTAMP YEAR 各类型都有具体的取值范围,超出或非法的其他值时,MySQL 会回退到 0.TIMESTAMP ...

  7. MySQL中日期和时间类型

    1 日期类型 MySql中关于日期的类型有Date/Datetime/Timestamp三种类型. 日期赋值时,允许"不严格"语法:任何标点符都可以用做日期部分或时间部分之间的间割 ...

  8. EF6中一个关于时间类型 datetime2 的坑

    在一个访问下位机的程序中,返回的时间戳有时候因断线产生0001年01月01日的时间,而原先使用拼接SQL进行数据存储的操作时,这个问题是可以跳过的. 这次把拼接SQL的部分重新改为EF进行管理,这个坑 ...

  9. 在Spring MVC 中配置自定义的类型转换器

    方法一: 实现spring mvc 自带的 Formatter 接口 1.创建一个类来实现Formatter接口 import org.springframework.format.Formatter ...

  10. Ext如何Gird中如何显示时间类型的列?

         rt,后台bean中的字段属性是Date类型,前台的model中的字段属性也设置为date类型,但是还是显示不出来,如何解决呢? 直接代码: grid中的COLUMN: Model中的定义:

随机推荐

  1. 华为云GaussDB(for Influx)单机版上线,企业降本增效利器来了

    本文分享自华为云社区<华为云GaussDB(for Influx)单机版上线,企业降本增效利器来了>,作者:GaussDB 数据库 . 1.背景 华为云GaussDB(for Influx ...

  2. WPF学习:Slider — 冒泡显示值

    想做一个下图所示的Slider,以冒泡的方式显示其Value值,该怎么做呢? 功能要求,当鼠标放在滑块上的时候,冒"泡"显示值:当滑块移动的时候,"泡"跟随移动 ...

  3. AutoEmbedding论文阅读笔记

    问题背景 目前推荐系统中, 在特征维度上低频特征和高频特征的维度是通过遍历mask特征获得到的auc衰减衡量特征对模型的重要度来决定的. 如果想提升模型效果, 在field层面上需要减少进行基于经验的 ...

  4. 《Python魔法大冒险》008 石像怪的挑战:运算符之旅

    小鱼和魔法师继续深入魔法森林.不久,他们来到了一个巨大的魔法石圈旁边.石圈中心有一个闪闪发光的魔法水晶,周围则是一些神秘的符号.但令人意外的是,水晶的旁边还有一个巨大的石像怪,它的眼睛散发着红色的光芒 ...

  5. jQuery获取select选中值的文本

    实际代码:var checkUserSelect=$("#checkUserSelect option:selected").text();//执法人员姓名 jQuery中获得选中 ...

  6. 响应式编程——初识 Flux 和 Mono

    by emanjusaka from ​ https://www.emanjusaka.top/archives/4 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文地址. 前言 Reactor ...

  7. 用 Rust 的 declarative macro 做了个小东西

    最近几天在弄 ddnspod 的时候,写了个宏: custom_meta_struct 解决什么问题 #[derive(Debug, Clone, serde::Serialize, serde::D ...

  8. window 安装多个低版本chrome测试

    最近在用next13做一个简单的项目,需要兼容chrome 60+以上版本,为了方便测试,特意在公司的台式机上安装了低版本. 这里简单记录下高版本覆盖低版本的问题,这个方法不影响Windows系统内已 ...

  9. Falcon-7B大型语言模型在心理健康对话数据集上使用QLoRA进行微调

      文本是参考文献[1]的中文翻译,主要讲解了Falcon-7B大型语言模型在心理健康对话数据集上使用QLoRA进行微调的过程.项目GitHub链接为https://github.com/iamaru ...

  10. RK3588平台产测之ArmSoM产品高温环境测试

    1. 简介专栏总目录 ArmSoM团队在产品量产之前都会对产品做几次专业化的功能测试以及性能压力测试,以此来保证产品的质量以及稳定性 优秀的产品都要进行严苛的多次全方位的功能测试以及性能压力测试才能够 ...