在日常开发工作中,我们进行会遇到将 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. 带你读论文丨S&P2019 HOLMES Real-time APT Detection

    本文分享自华为云社区<[论文阅读] (09)S&P2019 HOLMES Real-time APT Detection(溯源图)>,作者: eastmount . 摘要 本文提出 ...

  2. JOIN 关联表中 ON、WHERE 后面跟条件的区别

    SQL中join连接查询时条件放在on后与where后的区别 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和wh ...

  3. torch.nn基础学习教程 | PyTorch nn Basic Tutorial

    基于torch.nn搭建神经网络的基础教程大纲: 1. 引言 在我们开始深入探讨torch.nn之前,我们首先需要理解PyTorch及其神经网络库的基础知识.这一部分的内容将帮助你对PyTorch有一 ...

  4. shiro框架基本概念介绍

    什么是Shiro: Shiro 是一个强大灵活的开源安全框架,可以完全处理身份验证.授权.加密和会话管理 Shiro的核心功能包括: 身份验证(Authentication):验证用户的身份,确保用户 ...

  5. 纯干货!一文get昇腾Ascend C编程入门全部知识点

    本文分享自华为云社区<昇腾Ascend C编程入门教程>,作者:昇腾CANN . 2023年5月6日,在昇腾AI开发者峰会上,华为正式发布了面向算子开发场景的昇腾Ascend C编程语言. ...

  6. 【matplotlib基础】--坐标轴

    Matplotlib的坐标轴是用于在绘图中表示数据的位置的工具. 坐标轴是图像中的水平和垂直线,它们通常表示为 x 轴和 y 轴.坐标轴的作用是帮助观察者了解图像中数据的位置和大小,通常标有数字或标签 ...

  7. 《Python魔法大冒险》 001 序章:少年小鱼的不平凡一天

    在一个普通的城市里,生活着一个名叫小鱼的少年.他是一名初中生,但在班级里,他的学习成绩总是垫底.同学们经常取笑他,有时甚至戏称他为"倒数王". 放学后,小鱼一个人走在回家的路上,他 ...

  8. Jenkins 忘记密码|密码重置

    I. 当前环境 OS Version : AlmaLinux release 8.8 Jenkins Version : 2.414.1 II. 操作步骤 2.1 修改配置文件 1. SSH 登录服务 ...

  9. Hugging News #0912: Hugging Face 2 人入选时代周刊全球百大 AI 人物

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  10. k8s添加节点报[WARNING SystemVerification]: missing optional cgroups: blkio

    环境信息: ubuntu-master01  192.1681.195.128 ubuntu-work01    192.168.195.129 k8s版本 1.25.2 背景描述:初始环境是一个ma ...