UTC国际化时区改造步骤

✅ 一、后端(Spring Boot)改造

1. 数据库存储为 UTC 时间

确保数据库字段使用 datetime / timestamp 类型,并且设置为 UTC:

  • MySQL 推荐字段使用 DATETIME,并设置服务器或连接为 UTC。

  • 检查并设置数据库连接时区:

1
2
3
4
# application.yml 示例
spring:
datasource:
url: jdbc:mysql://localhost:3306/yourdb?serverTimezone=UTC

2. 全局时区设置为 UTC

1
2
3
4
5
6
7
8
// 添加配置类初始化全局时区
@Configuration
public class TimezoneConfig {
@PostConstruct
public void init() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
}

3. 使用 Instant / OffsetDateTime / ZonedDateTime 存储时间

在实体类中建议使用:

1
private Instant createdAt;

或者:

1
private OffsetDateTime createdAt;

4. 配置 Jackson 序列化为 ISO 8601 标准(带时区)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// 注册 JavaTimeModule 模块,使得 Jackson 能够正确处理 Java 8 时间类,而不会默认将它们转换为 `Date` 或时间戳(毫秒级)
mapper.registerModule(new JavaTimeModule());
// 禁用 将日期/时间作为时间戳(毫秒)输出的行为,使用默认 ISO 8601 格式
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 设置全局时区为 UTC
mapper.setTimeZone(TimeZone.getTimeZone("UTC"));
return mapper;
}
}

这将确保 JSON 格式类似于:

1
"createdAt": "2025-04-09T10:22:00Z"

5. Controller 层统一处理时间(可选)

为了更方便统一处理时间格式,可以使用全局参数解析器或注解格式配置:

1
2
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", timezone = "UTC")
private OffsetDateTime createdAt;

✅二、 前端 Vue 3 改造

1. 原则

  • 前后端时间格式统一为 ISO 8601(如 2025-04-09T10:22:00Z

  • 后端返回:2025-04-09T13:00:00Z(UTC)

  • 后端统一使用 Instant

  • 前端展示:自动转换为浏览器本地时间 2025-04-09 21:00:00(如北京时间)

  • 前端封装 formatUtcToLocal() / localToUtcString() 工具函数

  • 保持接口和组件代码结构不变


2. 安装轻量时间库:dayjs + 插件

1
2
npm install dayjs
npm install dayjs-plugin-utc dayjs-plugin-timezone

3. 创建统一工具函数模块(如 utils/time.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// utils/time.ts
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'

dayjs.extend(utc)
dayjs.extend(timezone)

// 当前用户所在时区
const userTimezone = dayjs.tz.guess()

// 将 UTC 字符串转成本地时间格式
export function formatUtcToLocal(utcString: string, format = 'YYYY-MM-DD HH:mm:ss') {
return dayjs.utc(utcString).tz(userTimezone).format(format)
}

// 将本地时间转成 UTC ISO 字符串(如提交给后端)
export function localToUtcString(localTime: string, format = undefined) {
const utc = dayjs(localTime).tz(userTimezone).utc()
return format ? utc.format(format) : utc.toISOString()
}

4. 在组件中按需使用(只替换时间展示地方)

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<div>创建时间:{{ formatUtcToLocal(user.createdAt) }}</div>
</template>

<script setup lang="ts">
import { formatUtcToLocal } from '@/utils/time'

const user = {
name: '小明',
createdAt: '2025-04-09T13:00:00Z'
}
</script>

💡不需要改动接口结构、不需要加额外字段,只需在展示位置调用 formatUtcToLocal 即可!


5. 表单中本地时间转 UTC(提交前转换)

1
2
3
// 假设用户输入的本地时间是字符串 '2025-04-09 21:00:00'
const utcString = localToUtcString('2025-04-09 21:00:00')
// 输出为 '2025-04-09T13:00:00Z'

6. 针对 element-plus

也可以在 DatePickerTable 中用封装字段格式化回调的方式替代默认渲染:

1
2
3
4
<el-table-column
prop="createdAt"
:formatter="(_, __, value) => formatUtcToLocal(value)"
label="创建时间" />

✅三、 数据库 MySql 改造

1. 会话时区设置

1
2
-- 确保数据库会话使用 UTC 时区
SET time_zone = '+00:00';

或者在 my.cnf 中添加:

1
default-time-zone = '+00:00'

2. 修改数据库字段类型

1
2
-- 将时间字段调整为 DATETIME
ALTER TABLE your_table MODIFY COLUMN created_at DATETIME;

UTC国际化时区改造步骤
http://eevann.cn/2025/04/09/utc-springboot-vue3/
作者
月下独白
发布于
2025年4月10日
许可协议