后端返回前端时间格式化

news2025/2/28 12:33:30

时间格式化的方法总共包含以下 5 种。

1.前端时间格式化

JS 版时间格式化

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

function dateFormat(fmt, date) {

    let ret;

    const opt = {

        "Y+": date.getFullYear().toString(),        // 年

        "m+": (date.getMonth() + 1).toString(),     // 月

        "d+": date.getDate().toString(),            // 日

        "H+": date.getHours().toString(),           // 时

        "M+": date.getMinutes().toString(),         // 分

        "S+": date.getSeconds().toString()          // 秒

        // 有其他格式化字符需求可以继续添加,必须转化成字符串

    };

    for (let k in opt) {

        ret = newRegExp("(" + k + ")").exec(fmt);

        if (ret) {

            fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))

        };

    };

    return fmt;

}

方法调用:

1

2

3

4

let date = newDate();

dateFormat("YYYY-mm-dd HH:MM:SS", date);

>>> 2021-07-2521:45:12

2.SimpleDateFormat格式化

使用 SimpleDateFormat 来进行时间格式化,它也是 JDK 8 之前重要的时间格式化方法,它的核心实现代码如下:

1

2

3

4

// 定义时间格式化对象和定义格式化样式

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

// 格式化时间对象

String date = dateFormat.format(new Date())

接下来我们使用 SimpleDateFormat 来实现一下本项目中的时间格式化,它的实现代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

@RequestMapping("/list")

public List<UserInfo> getList() {

    // 定义时间格式化对象

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    List<UserInfo> list = userMapper.getList();

    // 循环执行时间格式化

    list.forEach(item -> {

        // 使用预留字段 ctime 接收 createtime 格式化的时间(Date->String)

        item.setCtime(dateFormat.format(item.getCreatetime()));

        item.setUtime(dateFormat.format(item.getUpdatetime()));

    });

    return list;

}

程序执行结果如下:

从上述结果可以看出,时间格式化没有任何问题,以及到底我们预想的目的了。但细心的读者会发现,为什么接口的返回字段咋变了呢?(之前的字段是 createtime 现在却是 ctime…)

这是因为使用 #SimpleDateFormat.format 方法之后,它返回的是一个 String 类型的结果,而我们之前的 createtime 和 updatetime 字段都是 Date 类型的,因此它们是不能接收时间格式化得结果的。

所以此时我们就需要在实体类 UserInfo 新增两个字符串类型的“时间”字段,再将之前 Data 类型的时间字段进行隐藏,最终实体类 UserInfo 的实现代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Data;

import java.util.Date;

@Data

publicclass UserInfo {

    privateint id;

    private String username;

    @JsonIgnore// 输出结果时隐藏此字段

    private Date createtime;

    // 时间格式化后的字段

    private String ctime;

    @JsonIgnore// 输出结果时隐藏此字段

    private Date updatetime;

    // 时间格式化后的字段

    private String utime;

}

我们可以使用 @JsonIgnore 注解将字段进行隐藏,隐藏之后的执行结果如下:

3.DateTimeFormatter格式化

JDK 8 之后,我们可以使用 DateTimeFormatter 来替代 SimpleDateFormat,因为 SimpleDateFormat 是非线程安全的,而 DateTimeFormatter 是线程安全的,所以如果是 JDK 8 以上的项目,尽量使用 DateTimeFormatter 来进行时间格式化。

DateTimeFormatter 格式化的代码和 SimpleDateFormat 类似,具体实现如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

@RequestMapping("/list")

public List<UserInfo> getList() {

    // 定义时间格式化对象

    DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    List<UserInfo> list = userMapper.getList();

    // 循环执行时间格式化

    list.forEach(item -> {

        // 使用预留字段 ctime 接收 createtime 格式化的时间(Date->String)

        item.setCtime(dateFormat.format(item.getCreatetime()));

        item.setUtime(dateFormat.format(item.getUpdatetime()));

    });

    return list;

}

执行结果如下所示:

DateTimeFormatter 和 SimpleDateFormat 在使用上的区别是 DateTimeFormatter 是用来格式化 JDK 8 提供的时间类型的,如 LocalDateTime,而 SimpleDateFormat 是用来格式化 Date 类型的,所以我们需要对 UserInfoer 实体类做如下的修改:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Data;

import java.time.LocalDateTime;

@Data

publicclass UserInfo {

    privateint id;

    private String username;

    @JsonIgnore

    private LocalDateTime createtime;

    private String ctime;

    @JsonIgnore

    private LocalDateTime updatetime;

    private String utime;

}

我们可以使用 LocalDateTime 来接收 MySQL 中的 datetime 类型。

4.全局时间格式化

以上两种后端格式化的实现都有一个致命的缺点,它们在进行时间格式化的时候,都需要对核心业务类做一定的修改,这就相当为了解决一个问题,又引入了一个新的问题,那有没有简单一点、优雅一点的解决方案呢?

答案是:有的。我们可以不改任何代码,只需要在配置文件中设置一下就可以实现时间格式化的功能了。

首先,我们找到 Spring Boot 的配置文件 application.properties(或 application.yml),只需要在 application.properties 配置文件中添加以下两行配置:

1

2

3

4

# 格式化全局时间字段

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

# 指定时间区域类型

spring.jackson.time-zone=GMT+8

这样设置之后,我们将原始的 UserInfo 和 UserController 进行还原。

UserInfo 实现代码如下:

1

2

3

4

5

6

7

8

9

10

import lombok.Data;

import java.util.Date;

@Data

publicclass UserInfo {

    privateint id;

    private String username;

    private Date createtime;

    private Date updatetime;

}

UserController 实现代码:

1

2

3

4

@RequestMapping("/list")

public List<UserInfo> getList() {

    return userMapper.getList();

}

然后我们运行程序,看到的执行结果如下:

从以上结果和代码可以看出,我们只需要在程序中简单配置一下,就可以实现所有时间字段的格式化了。

实现原理分析为什么在配置文件中设置一下,就可以实现所有时间字段的格式化了呢?

1

2

3

4

# 格式化全局时间字段

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

# 指定时间区域类型

spring.jackson.time-zone=GMT+8

这是因为 Controller 在返回数据时,会自动调用 Spring Boot 框架中内置的 JSON 框架 Jackson,对返回的数据进行统一的 JSON 格式化处理,在处理的过程中它会判断配置文件中是否设置了“spring.jackson.date-format=yyyy-MM-dd HH:mm:ss”,如果设置了,那么 Jackson 框架在对时间类型的字段输出时就会执行时间格式化的处理,这样我们就通过配置来实现全局时间字段的格式化功能了。

为什么要指定时间区域类型“spring.jackson.time-zone=GMT+8”呢?

最现实的原因是,如果我们不指定时间区域类型,那么查询出来的时间就会比预期的时间少 8 个小时,这因为我们(中国)所处的时间区域比世界时间少 8 个小时导致的,而当我们设置了时区之后,我们的时间查询才会和预期时间保持一致。

GMT 是什么?时间区域设置中的“GMT” 是什么意思?

Greenwich Mean Time (GMT) 格林尼治时间,也叫做世界时间。

格林尼治时间格林尼治是英国伦敦南郊原皇家格林尼治天文台所在地,地球本初子午线的标界处,世界计算时间和经度的起点。以其海事历史、作为本初子午线的标准点、以及格林尼治时间以其命名而闻名于世。这里地势险要,风景秀丽,兼具历史和地方风情,也是伦敦在泰晤士河的东方门户。

不光是天文学家使用格林尼治时间,就是在新闻报刊上也经常出现这个名词。我们知道各地都有各地的地方时间。如果对国际上某一重大事情,用地方时间来记录,就会感到复杂不便.而且将来日子一长容易搞错。因此,天文学家就提出一个大家都能接受且又方便的记录方法,那就是以格林尼治的地方时间为标准。

以本初子午线的平子夜起算的平太阳时。又称格林尼治平时或格林尼治时间。各地的地方平时与世界时之差等于该地的地理经度。1960年以前曾作为基本时间计量系统被广泛应用。由于地球自转速率曾被认为是均匀的,因此在1960年以前,世界时被认为是一种均匀时。由于地球自转速度变化的影响,它不是一种均匀的时间系统,它与原子时或力学时都没有任何理论上的关系,只有通过观测才能对它们进行比较。后来世界时先后被历书时和原子时所取代,但在日常生活、天文导航、大地测量和宇宙飞行等方面仍属必需;同时,世界时反映地球自转速率的变化,是地球自转参数之一,仍为天文学和地球物理学的基本资料。

5.部分时间格式化

某些场景下,我们不需要对全局的时间都进行统一的处理,这种情况我们可以使用注解的方式来实现部分时间字段的格式化。

我们需要在实体类 UserInfo 中添加 @JsonFormat 注解,这样就可以实现时间的格式化功能了,实现代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

import com.fasterxml.jackson.annotation.JsonFormat;

import lombok.Data;

import java.util.Date;

@Data

publicclass UserInfo {

    privateint id;

    private String username;

    // 对 createtime 字段进行格式化处理

    @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone = "GMT+8")

    private Date createtime;

    private Date updatetime;

}

修改完代码之后,我们运行项目执行结果如下:

从上述结果可以看出,使用注解的方式也可以实现时间的格式化。它的实现原理和第 4 种时间格式化的实现原理类似,都是在返回数据之前,对相应的字段进行时间格式化的处理。

总结

本文我们介绍了 5 种时间格式化的实现方法,其中第 1 种为前端时间格式化的方法,后 4 种为后端格式化的方法,SimpleDateFormat 和 DateTimeFormatter 格式化的方法更适用普通的 Java 项目,其中 SimpleDateFormat 是非线程安全的,而 DateTimeFormatter 是线程安全的,但它们都不是 Spring Boot 项目中最优的时间格式化方案。

如果是 Spring Boot 的项目,推荐使用第 4 种全局时间格式化或第 5 种局部时间格式化的方式,这两种实现方式都无需修改核心业务代码,只需要简单的配置一下,就可以完成时间的格式化功能了。

参考:springboot时间格式化的五种方法总结(解决后端传给前端的时间显示不一致)_java_脚本之家

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

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

相关文章

挂耳式耳机哪个牌子好性价比高、五大招牌力作精选归纳

如果说你很喜欢户外运动&#xff0c;日常生活中也是需要经常佩戴耳机&#xff0c;那么你一定有了解到耳机是开放式耳机&#xff0c;这类耳机无论在户外运动防水防汗还是在耳朵健康方面都具备它的优点&#xff0c;在市面上是很受欢迎的。 但面对市面上不同品牌的耳机都会显得眼…

【面试干货】深入理解Java中的final关键字

【面试干货】深入理解Java中的final关键字 一、被 final 修饰的类二、被 final 修饰的方法三、被 final 修饰的变量四、被 final 修饰的常量 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java中&#xff0c;final关键字有多种用途&…

组合和外观模式

文章目录 组合模式1.引出组合模式1.院系展示需求2.组合模式基本介绍3.组合模式原理类图4.解决的问题 2.组合模式解决院系展示1.类图2.代码实现1.AbsOrganizationComponent.java 总体抽象类用于存储信息和定义方法2.University.java 第一层&#xff0c;University 可以管理 Coll…

atcoder ABC 355-C题详解

atcoder ABC 355-C题详解 ​ Problem Statement There is an NN grid, where the cell at the i-th row from the top and the j-th column from the left contains the integer N(i−1)j. Over T turns, integers will be announced. On Turn i, the integer Ai​ is anno…

C++入门8 构造函数析构函数顺序|拷贝构造

一&#xff0c;构造函数析构函数 调用顺序 我们先来看下面的代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> using namespace std; class student { public:char my_name[20];int my_id;student(int a) {my_id a;co…

使用超声波麦克风阵列预测数控机床刀具磨损

预测性维护是使用传感器数据来推断机器状态&#xff0c;并从这些传感器数据中检测出在故障发生之前存在的缺陷或故障的过程。预测性维护在所有工业领域都是一种日益增长的趋势&#xff0c;包括轴承故障检测、齿轮磨损检测或往复式机器中的活塞磨损等许多其他例子。在预测性维护…

ADS基础教程20 - 电磁仿真(EM)参数化

EM介绍 一、引言二、参数化设置1.参数定义2.参数赋值3.创建EM模型和符号 四、总结 一、引言 参数化EM仿真&#xff0c;是在Layout环境下创建参数&#xff0c;相当于在原理图中声明变量。 二、参数化设置 1.参数定义 1&#xff09;在Layout视图&#xff0c;菜单栏中选中EM&g…

哈喽GPT-4o——对GPT-4o 写论文的思考与看法

目录 几小时即可完成一份1万字论文的编写1、改写降重2、同义词替换降重3、避免连续相同4、缩写扩写降重5、关键词汇替换降重6、句式变换降重7、逻辑重组8、综合改写9、数据呈现方式变更10、概念解释降重 大家好&#xff0c;我是哪吒。 在ChatGPT4o对话框中输入&#xff1a;写一…

继承-进阶-易错点

子类同名方法隐藏父类方法 即使调用不匹配也不会再去父类寻找&#xff0c;而是直接报错 //下面代码输出结果&#xff1a;( )&#xfeff;class A { public:void f(){ cout<<"A::f()"<<endl; }int a; };class B : public A { public:void f(int a){c…

若依微服务Docker部署验证码出不来怎么办?

最近,有许多人反馈在使用 Docker 部署若依微服务项目时,遇到验证码无法显示的问题。本文将重点介绍解决该问题的注意事项以及整个项目的部署流程。之前我们也撰写过微服务部署教程,本文将在此基础上进行优化和补充。你也可以参考我之前写的部署教程:https://yang-roc.blog.…

做材料科学领域研究热点:高通量多尺度材料计算和机器学习

研究背景 材料科学是一个重要领域&#xff0c;涉及物质的研究和利用。随着科技进步&#xff0c;材料学已成为多学科交叉的前沿领域之一&#xff0c;融合物理、化学、数学、信息、力学和计算科学等知识。寻找更坚固的新材料已成为当今急需解决的问题。 材料基因工程作为一项颠覆…

万相台的功能是什么?如何使用万相台?

1.特点&#xff1a; 万相台是一个智能渠道&#xff0c;可控性弱&#xff0c;高转化&#xff0c;人群&关键词是黑盒&#xff1b; 2.场景多&#xff1a; 有拉新快、活动加速、上新快、货品加速、活动加速、多目标直投、全站推等&#xff1b; 3.扣费逻辑&#xff1a;cpc付…

Elasticsearch:简化数据流的数据生命周期管理

作者&#xff1a;来自 Elastic Andrei Dan 今天&#xff0c;我们将探索 Elasticsearch 针对数据流的新数据管理系统&#xff1a;数据流生命周期&#xff0c;从版本 8.14 开始提供。凭借其简单而强大的执行模型&#xff0c;数据流生命周期可让n 你专注于数据生命周期的业务相关方…

动态规划-简单多状态dp问题 -- 按摩师

动态规划-简单多状态dp问题 – 按摩师 文章目录 动态规划-简单多状态dp问题 -- 按摩师题目重现算法流程示例代码 题目重现 题目链接&#xff1a;按摩师 - 力扣 一个有名的按摩师会收到源源不断的预约请求&#xff0c;每个预约都可以选择接或不接。在每次预约服务之间要有休息时…

Linux网络编程:多路转接|select|poll

目录 前言&#xff1a; 1.IO多路转接---select 1.1.接口认识 1.2.select如何进行多路转接 1.3.select多路转接的优缺点 2.IO多路转接---poll 2.1.接口认识 2.2.poll如何进行多路转接 2.3.poll多路转接优缺点 前言&#xff1a; 多路转接&#xff08;也称为IO多路复用&a…

留住马斯克和AI,股价连续大涨,但特斯拉还是贵?

留住马斯克和AI&#xff0c;股价连续大涨&#xff0c;但特斯拉还是贵&#xff1f; 特斯拉股东们花了560亿美元留住马斯克&#xff0c;但特斯拉的前景依旧迷雾重重&#xff0c;估值比一众科技巨头贵&#xff0c;汽车一季度销量疲弱&#xff0c;股价今年来累计下跌29%&#xff0…

mysql导入sql文件失败及解决措施

1.报错找不到表 1.1 原因 表格创建失败&#xff0c;编码问题mysql8相较于mysql5出现了新的编码集 1.2解决办法&#xff1a; 使用vscode打开sql文件ctrlh&#xff0c;批量替换&#xff0c;替换到你所安装mysql支持的编码集。 2.timestmp没有设置默认值 Error occured at:20…

LangChain入门学习笔记(三)—— Model I/O之Prompts

如果说LCEL是粘合剂&#xff0c;那么它需要粘合起来的要素就是各种组件。其中最核心的要素就是LangChain官方文档中定义的Model I/O&#xff1a;Prompts、Chat Models、LLMs和Output Parsers。这4个基本组件&#xff0c;可以处理基本的用户输入并通过大模型处理后按要求输出。 …

SpringBoot的Mybatis-plus实战之核心功能

文章目录 一、条件构造器二、自定义SQL第一步、基于wrapper构建where条件第二步、在mapper中声明变量名称第三步、自定义SQL 本篇继续MybatisPlus核心功能 一、条件构造器 MybatisPlus 支持各种复杂的where条件&#xff0c;可满足日常开发的所有需求。 使用到wrapper构造器&am…

代理服务

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在爬取网页的过程中&#xff0c;经常会出现不久前可以爬取的网页现在无法爬取了&#xff0c;这是因为您的IP被爬取网站的服务器所屏蔽了。此时代理服…