当前位置: 首页 > article >正文

从 ISO 到 GMT+8:Vue 前端时间格式的奇妙之旅!


🎉 “从 ISO 到 GMT+8:Vue 前端时间格式的奇妙之旅!” 🎉

作者:小丁 | 日期:2025-03-04

嘿,各位前端探险家 👩‍💻👨‍💻!今天我要带你们走进一个时间格式的“变形记”:从前端的 ISO 格式("2025-03-04T07:28:17.058Z")到后端期待的 GMT+8 "yyyy-MM-dd HH:mm:ss""2025-03-04 15:28:17"),我如何在 Vue 项目中搞定这个“时间旅行”的小挑战?别急,拿好你的爆米花 🍿,跟我一起揭开这段代码冒险的幕后故事吧!


🎬 故事开场:时间格式的“误会”

有一天,我在调试一个 Vue 项目,子组件 <ave-form> 负责收集用户寄样信息。代码里有个关键函数:

private handleExpressCompanyChange(value: string) {
  if (value) {
    this.form.sampleSendTime = new Date().toISOString();
  }
}

逻辑很简单:用户一选快递公司,sampleSendTime 就自动填上当前时间,格式是 ISO 8601 的 "2025-03-04T07:28:17.058Z"。我得意地提交表单,期待后端完美接收。结果呢?后端报错:

Cannot deserialize value of type `java.util.Date` 
from String "2025-03-04T07:28:17.058Z": 
expected format "yyyy-MM-dd HH:mm:ss"

后端冷冰冰地告诉我,它想要的是 @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss"),也就是 "2025-03-04 15:28:17"。这下尴尬了,前端和后端就像在“跨时区吵架”:一个讲国际标准,一个要东八区时间!😂


🕵️‍♂️ 破案第一步:时间格式的“身份危机”

让我们先看看问题出在哪里:

  • 前端输出new Date().toISOString() 生成 "2025-03-04T07:28:17.058Z"
    • T 分隔日期和时间。
    • .058 是毫秒。
    • Z 表示 UTC 时间(零时区)。
  • 后端期待"2025-03-04 15:28:17"
    • T,无毫秒。
    • 空格分隔。
    • GMT+8 时区(比 UTC 早 8 小时)。

这就好比前端递给后端一张“国际护照” ✈️,后端却说:“我只认本地身份证!” 🪪 显然,我们得把时间“改头换面”。


🛠️ 动手改造:从 ISO 到 GMT+8

我决定在前端动手,把时间格式调整到后端喜欢的模样。目标:

  1. 去掉 T 和毫秒,改用空格。
  2. 调整为 GMT+8 时区。
  3. 输出 "yyyy-MM-dd HH:mm:ss"

初步尝试:手动格式化

我写了个小函数,把 Date 对象“打扮”成 GMT+8 的样子:

private formatDateToGMT8(date: Date): string {
  const offset = 8 * 60; // GMT+8 是 8 小时,转换为分钟
  const localDate = new Date(date.getTime() + offset * 60 * 1000); // 调整为 GMT+8
  const pad = (num: number) => num.toString().padStart(2, '0');
  return `${localDate.getUTCFullYear()}-${pad(localDate.getUTCMonth() + 1)}-${pad(localDate.getUTCDate())} ` +
         `${pad(localDate.getUTCHours())}:${pad(localDate.getUTCMinutes())}:${pad(localDate.getUTCSeconds())}`;
}

private handleExpressCompanyChange(value: string) {
  if (value) {
    this.form.sampleSendTime = this.formatDateToGMT8(new Date());
  }
}
  • getTime() + 偏移:把时间戳加 8 小时,模拟 GMT+8。
  • pad:补齐两位数,比如 7 变成 07
  • 结果:如果现在是 UTC 的 "2025-03-04T07:28:17",加上 8 小时后,输出 "2025-03-04 15:28:17"

提交后,后端终于不吵了,数据库里存下了完美的 "2025-03-04 15:28:17"!🎉


🎨 SVG 图解:时间的“变装秀”

为了让大家看得更清楚,我用 SVG 画了个“时间变形记”:

前端 ISO 时间 "2025-03-04T07:28:17.058Z" 后端 GMT+8 时间 "2025-03-04 15:28:17" +8小时 & 格式化 (去掉 T 和毫秒) +8小时 & 格式化 (去掉 T 和毫秒) +8小时 & 格式化 (去掉 T 和毫秒)

🧠 为什么删掉初始值?

顺便说一句,我还干了件“断舍离”的事:删掉了 form 的初始赋值:

// 之前
private form: any = {
  sampleTrackingNumber: '',
  sampleExpressCompany: '',
  sampleSendTime: new Date().toISOString()
};

// 现在
private form: any = {};

为啥?因为子组件有个 @Watch('value'),每次父组件传 value(比如空对象 {})时,form 都会被覆盖,初始值压根没机会“上场”!删了它,代码更干净,反正 sampleSendTime 在选择快递公司时会重新赋值。🏃‍♂️


🌟 收获与反思

这次时间格式的调整让我学到了几招:

  1. 前端后端要“谈恋爱”:时间格式得统一,别让一方“国际派”,一方“本地派”,不然迟早“分手”!😅
  2. 时区是个坑toISOString() 是 UTC 时间,得手动调整到目标时区(比如 GMT+8)。
  3. 精简代码有回报:没用的初始值果断删,既省内存又少烦恼。

最终,我的表单数据顺利提交,后端开心地存下了 "2025-03-04 15:28:17",项目又迈进了一小步!🏆


🛠️ 代码锦囊:留给你的“时间魔法”

想复刻这个魔法?直接抄走这段代码吧:

private formatDateToGMT8(date: Date): string {
  const offset = 8 * 60; // GMT+8 偏移(分钟)
  const localDate = new Date(date.getTime() + offset * 60 * 1000);
  const pad = (num: number) => num.toString().padStart(2, '0');
  return `${localDate.getUTCFullYear()}-${pad(localDate.getUTCMonth() + 1)}-${pad(localDate.getUTCDate())} ` +
         `${pad(localDate.getUTCHours())}:${pad(localDate.getUTCMinutes())}:${pad(localDate.getUTCSeconds())}`;
}

private handleExpressCompanyChange(value: string) {
  if (value) {
    this.form.sampleSendTime = this.formatDateToGMT8(new Date());
  }
}

💬 小彩蛋:你的时间故事

你有没有遇到过类似的“时间格式纠葛”?是前端后端“吵架”,还是时区让你头晕?评论区聊聊吧!我带着代码和咖啡 ☕,随时帮你解惑!✌️


在这里插入图片描述


http://www.kler.cn/a/571317.html

相关文章:

  • 软件接口(API)自动化测试 顶级框架 封装
  • Spark 中分区相关设置
  • 拉格朗日对偶性(Lagrangian Duality)详解
  • 国产编辑器EverEdit - 优化性能的一些设置项
  • 74道高级Java面试合集,java开发模式面试题
  • 【http://noi.openjudge.cn/】4.3算法之图论——1538:Gopher II
  • 14天 -- Redis 的持久化机制有哪些?Redis 主从复制的实现原理是什么? Redis 数据过期后的删除策略是什么?
  • DeepSeek开源周-汇总
  • VB6网络通信软件开发,上位机开发,TCP网络通信,读写数据并处理,完整源码下载
  • Leetcode 3472. Longest Palindromic Subsequence After at Most K Operations
  • 【零基础到精通Java合集】第十六集:多线程与并发编程
  • vue2(笔记)4.0vueRouter.声明式/编程式导航以及跳转传参.重定向
  • 浅谈汽车系统电压优缺点分析
  • PyTorch 中结合迁移学习和强化学习的完整实现方案
  • 【2025rust笔记】超详细,小白,rust基本语法
  • vue 提升html2canvas渲染速度
  • 第十天-字符串:编程世界的文本基石
  • 深入 Vue.js 组件开发:从基础到实践
  • 深入探索像ChatGPT这样的大语言模型
  • 记一次渗透测试实战:SQL注入漏洞的挖掘与利用