「有问必答」Go如何优雅的对时间进行格式化?

news2024/12/26 21:12:22

昨天 交流群 关于「Go如何优雅的对时间进行格式化?」展开了讨论:

在这里插入图片描述

在这里插入图片描述

咋搞捏?

如何在不循环的情况下,把列表数据结构体的时间修改为咱们习惯的格式,而不是UTC模式

我们要实现的效果如下:

  • created_at 是go语言原生的方式,
  • updated_at 是我们期望优化成的方式

{
    "code": 200,
    "data": {
        "count": 12,
        "info": [
            {
                "created_at": "2021-03-17T07:11:24+08:00" //原生方式
                "updated_at": "2021-03-17 07:11:24",  //需要优化成这种
            }
        ]
    },
    "message": "成功"
}

引入神器

  1. 首先我们引入一个包,在控制台运行
go get github.com/liamylian/jsontime
  1. 下载相关依赖
go mod download
  1. 修改结构体,声明要处理时间的字段
type Order struct {
    .
    .
    .
	CreatedAt       time.Time `json:"created_at" time_format:"sql_datetime" time_utc:"false"`       // 格式化时间示例
	UpdatedAt       string  `json:"updated_at"`       // 原生状态示例
}
  1. 取值时调用MarshalToString把结构体数据转为字符串
  2. 但是转完的字符串存在反斜线的问题,使用json.RawMessage()处理一下
var timeJson = jsontime.ConfigWithCustomTimeFormat

func AllOrder(c *gin.Context) {
	limitStr := c.DefaultQuery("limit", "10")
	pageStr := c.DefaultQuery("page", "0")
	orderType := c.DefaultQuery("orderType", "desc")
	orderField := c.DefaultQuery("orderField", "id")
	orderSql := orderField + " " + orderType
	limit, _ := strconv.Atoi(limitStr)
	page, _ := strconv.Atoi(pageStr)
	count, res := model.QueryOrder(0, limit, page, orderSql)
	//处理1:MarshalToString
	bytes, _ := timeJson.MarshalToString(&res)

	jsonInfo := map[string]interface{}{
		"count": count,
		//处理2:解决反斜线的问题
		"info":  json.RawMessage(bytes), 
	}

	c.JSON(http.StatusOK, ReturnJson{
		http.StatusOK,
		jsonInfo,
		"成功",
	})
}

我们最终实现出来的效果

{
    "code": 200,
    "data": {
        "count": 12,
        "info": [
            {
                "updated_at": "2021-03-17 07:13:24",
                "created_at": "2021-03-17 07:11:24",  
            }
        ]
    },
    "message": "成功"
}

好了,通过引入上面的神器就解决了我们的问题。

我们再深入理解一下time包的使用:

time包

time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。

时间类型

time.Time类型表示时间。我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息。示例代码如下:

func timeDemo() {
	now := time.Now() //获取当前时间
	fmt.Printf("current time:%v\n", now)

	year := now.Year()     //年
	month := now.Month()   //月
	day := now.Day()       //日
	hour := now.Hour()     //小时
	minute := now.Minute() //分钟
	second := now.Second() //秒
	fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)
}

时间戳

时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数。它也被称为Unix时间戳(UnixTimestamp)。

基于时间对象获取时间戳的示例代码如下:

func timestampDemo() {
	now := time.Now()            //获取当前时间
	timestamp1 := now.Unix()     //时间戳
	timestamp2 := now.UnixNano() //纳秒时间戳
	fmt.Printf("current timestamp1:%v\n", timestamp1)
	fmt.Printf("current timestamp2:%v\n", timestamp2)
}

使用time.Unix()函数可以将时间戳转为时间格式。

func timestampDemo2(timestamp int64) {
	timeObj := time.Unix(timestamp, 0) //将时间戳转为时间格式
	fmt.Println(timeObj)
	year := timeObj.Year()     //年
	month := timeObj.Month()   //月
	day := timeObj.Day()       //日
	hour := timeObj.Hour()     //小时
	minute := timeObj.Minute() //分钟
	second := timeObj.Second() //秒
	fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)
}

时间间隔

time.Duration是time包定义的一个类型,它代表两个时间点之间经过的时间,以纳秒为单位。time.Duration表示一段时间间隔,可表示的最长时间段大约290年。

time包中定义的时间间隔类型的常量如下:

const (
    Nanosecond  Duration = 1
    Microsecond          = 1000 * Nanosecond
    Millisecond          = 1000 * Microsecond
    Second               = 1000 * Millisecond
    Minute               = 60 * Second
    Hour                 = 60 * Minute
)

例如:time.Duration表示1纳秒,time.Second表示1秒。

时间操作

Add
我们在日常的编码过程中可能会遇到要求时间+时间间隔的需求,Go语言的时间对象有提供Add方法如下:

func (t Time) Add(d Duration) Time
举个例子,求一个小时之后的时间:

func main() {
	now := time.Now()
	later := now.Add(time.Hour) // 当前时间加1小时后的时间
	fmt.Println(later)
}

Sub

求两个时间之间的差值:

func (t Time) Sub(u Time) Duration

返回一个时间段t-u。如果结果超出了Duration可以表示的最大值/最小值,将返回最大值/最小值。要获取时间点t-d(d为Duration),可以使用t.Add(-d)。

Equal

func (t Time) Equal(u Time) bool

判断两个时间是否相同,会考虑时区的影响,因此不同时区标准的时间也可以正确比较。本方法和用t==u不同,这种方法还会比较地点和时区信息。

Before

func (t Time) Before(u Time) bool

如果t代表的时间点在u之前,返回真;否则返回假。

After

func (t Time) After(u Time) bool

如果t代表的时间点在u之后,返回真;否则返回假。

定时器

使用time.Tick(时间间隔)来设置定时器,定时器的本质上是一个通道(channel)。

func tickDemo() {
	ticker := time.Tick(time.Second) //定义一个1秒间隔的定时器
	for i := range ticker {
		fmt.Println(i)//每秒都会执行的任务
	}
}

时间格式化

时间类型有一个自带的方法Format进行格式化,需要注意的是Go语言中格式化时间模板不是常见的Y-m-d H:M:S而是使用Go的诞生时间2006年1月2号15点04分(记忆口诀为2006 1 2 3 4)。

也许这就是技术人员的浪漫吧(当然,也有人说这事瞎搞

补充:如果想格式化为12小时方式,需指定PM。

func formatDemo() {
	now := time.Now()
	// 格式化的模板为Go的出生时间2006年1月2号15点04分 Mon Jan
	// 24小时制
	fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
	// 12小时制
	fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
	fmt.Println(now.Format("2006/01/02 15:04"))
	fmt.Println(now.Format("15:04 2006/01/02"))
	fmt.Println(now.Format("2006/01/02"))
}

解析字符串格式的时间

now := time.Now()
fmt.Println(now)
// 加载时区
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
	fmt.Println(err)
	return
}
// 按照指定时区和指定格式解析字符串时间
timeObj, err := time.ParseInLocation("2006/01/02 15:04:05", "2019/08/04 14:15:20", loc)
if err != nil {
	fmt.Println(err)
	return
}
fmt.Println(timeObj)
fmt.Println(timeObj.Sub(now))

欢迎关注 ❤

我的微信:wangzhongyang1993

视频号:王中阳Go

公众号:程序员升职加薪之旅

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/652436.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android Framework分析Zygote进程的启动过程

Zygote进程是Android系统中的一个重要进程,其主要作用是预热Java虚拟机和启动应用进程。本文将着重分析Zygote进程的启动过程,结合代码注释和示例代码,让读者更好地理解Zygote的内部工作原理。 Zygote进程的启动过程 Zygote进程的启动过程包…

Python3 里面的四舍五入

目录 1.一般的四舍五入 : 使用内置的round函数 1.1官方文档: 1.2 举例说明: 2.python3里的格式化输出 format 2.1 记忆法则 :填齐宽 逗精类 2.2 format实质就是通过设置精度间接使用了等效round函数,但是不要把格式化输出和四…

chatgpt赋能python:Python是如何帮助确定location的?

Python是如何帮助确定location的? 什么是location? 在SEO中,location指的是特定页面、文章或者商铺在搜索结果中的排名位置。通常来说,更高的location意味着更多的点击率和流量,因此在SEO中,确定location…

独立站思考:Facebook选品测品

导语:对于独立站而言,获取稳定的流量是至关重要的。本文将探讨如何利用Facebook的选品测品功能,精准找到用户并提高点击率,以及如何通过数据分析优化,提高转化率并快速产生订单。 第一部分:精准定位用户的方…

Nodejs五、Express

零、文章目录 Nodejs五、Express 1、初识 Express (1)Express 简介 Express是什么 官方给出的概念:Express 是基于 Node.js 平台,快速、开放、极简的 Web 开发框架。 通俗的理解:Express 的作用和 Node.js 内置的 …

Swift 5.9 有哪些新特性(一)

文章目录 前言if 和 switch 表达式Value 和 Type 参数包 前言 虽然 Swift 6 已经在地平线上浮现,但 5.x 版本仍然有很多新功能-更简单的 if 和 switch 用法、宏、非可复制类型、自定义 actor 执行器等等都将在 Swift 5.9 中推出,再次带来了一个巨大的更…

矩阵补全文献汇总

[1] Nguyen L T , Kim J , Shim B .Low-Rank Matrix Completion: A Contemporary Survey[J].IEEE Access, 2019, PP(99):1-1.DOI:10.1109/ACCESS.2019.2928130. 几根棒子的一篇工作。基本结构可以借鉴。 适用于秩未知的矩阵补全文献汇总 [1] Fornasier M , Rauhut H , Ward…

报表岗位如何快速升职加薪?卷的心态要放平,工具要选对!

最近下班时一直看到做报表的部门每个人埋头苦干,不用说,这是又在忙半年度报告了。 现在,报表内卷现象十分严重,大家可能用的是一样的数据集,虽说每个人输出的报告可能结果差异不大,但懂得怎么利用工具&…

在HR眼里,IE证书早就不值钱了

大家好,我是老杨。 最近项目实在是忙,内容都写的少了一些,真的是有点力不从心的意思,人年纪大了,比不起当初年轻的自己了 和同事领导在一块儿的时间越多,就免不了聊到今年的就业环境。 我不提&#xff0…

Vue中如何进行代码编辑器与实时预览?

Vue中如何进行代码编辑器与实时预览? 在现代Web应用程序中,代码编辑器和实时预览已经成为了必不可少的一部分。Vue作为一款流行的JavaScript框架,也提供了一些工具和库,方便开发者在Vue中集成代码编辑器和实时预览功能。本文将介…

基于Eclipse+Java+Swing+Mysql实现超市销存管理系统

基于EclipseJavaSwingMysql实现超市销存管理系统 一、系统介绍二、功能展示1.登陆2.整体页面3.进货4.售货5.查询6、退出系统 三、数据库四、其它1.其他系统实现五.获取源码 一、系统介绍 系统实现了:商品进货、商品销售、库存查询 、进货查询、 售货查询、退出系统…

Date类(Java)

文章目录 1. 介绍2. 分析3. 方法3.1 Constructor()3.2 getTime()3.3 compareTo()3.4 equals() 1. 介绍 A. 类介绍:类Data表示特定的瞬间,可以精确到毫秒  Date类 有两个其他的函数。它允许把日期解释为年、月、日、小时、分钟和秒值  从 JDK 1.1 开始&…

Python自动化测试的配置层实现方式对标与落地 | 京东云技术团队

Python中什么是配置文件,配置文件如何使用,有哪些支持的配置文件等内容,话不多说,让我们一起看看吧~ 1 什么是配置文件? 配置文件是用于配置计算机程序的参数和初始化设置的文件,如果没有这些配置程序可能…

Vue中如何进行数据可视化关系图展示(如关系图谱)

Vue中如何进行数据可视化关系图展示(如关系图谱) 随着数据分析和可视化技术的发展,越来越多的应用开始使用关系图谱来展示数据之间的关系。在Vue中,我们可以使用第三方库Vis.js来实现关系图谱的展示,并通过Vue组件来进…

Java网络开发(Tomcat同步数据分页)—— 用Jsp语法 到 实现数据的分页展示 到 只看自己的数据 + 模糊查询 迭代升级

目录 引出0.jsp的使用和语法 & 报错和解决(1)后端共享,前端获取 ${pageInfo}(2)如果想获取pageInfo这个对象的某个属性值,用 点 属性 ${pageInfo.pages}(3)如果想回传&#xff…

java 学生信息管理系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 学生信息管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0…

IDEA执行Maven命令

在工作区的最右侧,IntelliJ IDEA 为我们提供了一个十分实用的窗口:Maven 工具窗口,通过它我们几乎可以完成所有与 Maven 相关的操作。 在 Maven 工具窗口中,我们可以通过以下 3 种方式中执行 Maven 命令: 使用 Run An…

RFID技术在工业自动化和生产流程优化方面的成功应用

您是否好奇于如何在工业场景中利用RFID技术实现更高效的操作和生产流程优化?ANDEAWELL作为国内知名的RFID工业识别设备供应商, 企业国产化替代的首选品牌,将带您深入探索RFID技术在工业领域的应用,揭示其优势和挑战,并…

召回率的概念

召回率 就是查出来的正确的数量除以所有正确的数量;准确率是用你查出来的正确的数量除以所有的数量(包含正确和不正确的数量)。 附上某位大佬的图:

激光盐密灰密测试仪

一、产品特点 KDYM-302L 激光盐密灰密测试仪采用检测技术将灰密测试与盐密测试合二为一,可同时检测出被测绝缘子的灰密度和盐密度,简化了绝缘子污秽检测的流程,非常适合在巡检现场和实验室使用。 二、主要特点 内置测试专用测试软件&#x…