【前端实战】如何封装日期格式化工具,满足后端 LocalDate 和 LocalDateTime 格式需求
在前后端分离开发中,日期时间数据的传递是个常见的难点。后端往往用 Java 的 LocalDate
和 LocalDateTime
类型接收日期数据:
LocalDate
要求字符串格式为yyyy-MM-dd
,不能有时间部分;LocalDateTime
要求格式为yyyy-MM-dd HH:mm:ss
,包含时分秒。
如果前端传递的日期时间格式不符合要求,后端 Jackson 反序列化会报错,导致接口调用失败,常见错误如:
Cannot deserialize value of type `java.time.LocalDate` from String "2024-01-31 13:42:30.0": Text '2024-01-31 13:42:30.0' could not be parsed, unparsed text found at index 10
一、为什么要封装日期格式化工具?
避免重复代码:项目里日期处理场景多,重复写
substr
或者日期格式转换很麻烦。统一日期格式:保证所有时间格式统一,方便维护和排查问题。
灵活适配后端需求:有时后端只需要日期,有时需要完整时间,封装函数可以灵活传参控制。
减少传参错误:前端统一调用工具函数,减少因格式不正确导致的接口调用失败
二、封装日期格式化函数示例
/*** 格式化日期为后端可识别字符串格式* @param {Date|string|null} date - 需要格式化的日期或字符串* @param {boolean} [includeTime=false] - 是否包含时间部分(时分秒),默认只输出年月日* @returns {string|null} 返回格式化后的字符串,如 '2024-08-12' 或 '2024-08-12 14:30:00',无效日期返回 null*/
export function formatDateForBackend(date, includeTime = false) {if (!date) return null;const d = new Date(date);if (isNaN(d)) return null;const y = d.getFullYear();const m = String(d.getMonth() + 1).padStart(2, '0');const day = String(d.getDate()).padStart(2, '0');if (!includeTime) {// 只返回年月日,满足 LocalDate 格式return `${y}-${m}-${day}`;} else {// 返回年月日时分秒,满足 LocalDateTime 格式const hh = String(d.getHours()).padStart(2, '0');const mm = String(d.getMinutes()).padStart(2, '0');const ss = String(d.getSeconds()).padStart(2, '0');return `${y}-${m}-${day} ${hh}:${mm}:${ss}`;}
}
三、示例分析
参数说明:
date
:可以是Date
对象,也可以是日期字符串;includeTime
:控制是否输出时分秒,默认false
。流程:
判断日期有效性,避免传空或非法值;
使用
Date
对象拆解年、月、日、时、分、秒;根据
includeTime
选择返回格式;对月、日、时、分、秒补零确保格式正确。
四、项目中的实际应用
举例:你有一个接口获取报销单列表,字段里有 createdOn
(时间戳或字符串),后端字段是 LocalDate
类型,必须是 yyyy-MM-dd
import { formatDateForBackend } from '@/utils/dateUtils'erpCoverBillHeadAPI({ orderNumber }).then(res => {this.interestCoverList = res.data.map(item => ({reimbursementDate: formatDateForBackend(item.createdOn, false), // 只要年月日settlementDate: formatDateForBackend(item.settlementDate, false),reimbursementCode: item.doCno || '',expenName: item.expenName || '',reimburser: item.createdBy || '',reimbursementAmount: parseFloat(item.bxAmount || 0),// 其他字段...}));console.log('转换后的报销数据:', this.interestCoverList);
}).catch(console.error);
这样保存之后的结果就只有年月了:
五、为什么要格式化日期?
因为后端如果收到字符串 "2024-01-31 13:42:30.0"
作为 LocalDate
类型,Jackson 会报错,因为 LocalDate
不能识别时间部分:
Text '2024-01-31 13:42:30.0' could not be parsed, unparsed text found at index 10
所以必须把时间截取为 "2024-01-31"
形式,才能让反序列化成功
六、总结
封装日期格式化工具是前端开发的好习惯,减少重复代码,提高代码质量;
灵活传递是否包含时间,应对不同后端字段需求;
保证接口传参的格式正确,避免接口调用失败;
与后端保持沟通,了解字段类型及格式要求,做好对应处理。