格式处理需求
相信每一个前端开发者都会遇到处理日期格式的问题,最好的方式当然是后端处理好,通过接口返回一个string字段到前端,前端就可以直接显示。但显然并不是所有的后端和规范都是这样做的,因此很多时候还是需要前端对日期格式进行处理。
时间处理的起点通常都是一个时间戳,然后根据具体需求将其转化成对应的年月日格式;于是最简单的处理方式就自然而然地产生了。
假如我们需要显示xxxx年xx月xx日 xx时xx分xx秒
export const formateYYYY_MM_DD = (
time: Date
): string => {
let Y = time.getFullYear();
let Mon = time.getMonth() + 1;
let D = time.getDate();
let H = time.getHours();
let Min = time.getMinutes();
let S = time.getSeconds();
return `${Y}年${Mon}月${D}日 ${H}时${Min}分${S}秒`
}
import { formateYYYY_MM_DD } from "./index";
console.log(formateYYYY_MM_DD(new Date(1672506061000)));
// 2023年1月1日 1时1分1秒
更进一步
当我们心满意足地写完上面的代码,开始写下一个页面的时候,忽然发现设计稿上的时间显示格式变成了xxxx-xx-xx xx:xx:xx
好办,再来一个方法
export const formateYYYYMMDD = (
time: Date
): string => {
let Y = time.getFullYear();
let Mon = time.getMonth() + 1;
let D = time.getDate();
let H = time.getHours();
let Min = time.getMinutes();
let S = time.getSeconds();
return `${Y}-${Mon}-${D} ${H}:${Min}:${S}`
}
import { formateYYYYMMDD } from "./index";
console.log(formateYYYYMMDD(new Date(1672506061000)));
// 2023-1-1 1:1:1
问题解决了,但显然并不是最好的方法。最大的弊端在于,面对各种各样的时间格式,针对每一个格式都要单独写一个方法,那如果一个页面足够花哨,需要显示的格式足够多,就需要不停地import新方法,变得越来越难以维护。
优化的思路自然是向上抽离,将转换整理到一个方法里;于是很自然地会想到,我可以增加一个格式的参数,将要输出的格式传进来。
export const formateYYYY_MM_DD = (
time: Date,
formate: string = 'Y年Mon月D日'
): string => {
let Y = time.getFullYear();
let Mon = time.getMonth() + 1;
let D = time.getDate();
let H = time.getHours();
let Min = time.getMinutes();
let S = time.getSeconds();
switch (formate) {
case 'Y年Mon月D日':
return `${Y}年${Mon}月${D}日 ${H}时${Min}分${S}秒`
case 'Y-Mon-D':
return `${Y}-${Mon}-${D} ${H}:${Min}:${S}`
default:
return ''
}
}
再进一步
上面的代码确实已经解决了大部分问题,但随着格式的增加,switch的分支必然也会越来越多。代码越来越臃肿的同时,对于分支的命名也是一件让人头痛的事。
那有没更进一步的方法呢?
让我们继续分析问题,其实所有的日期格式无非都是年月日时分秒的排列组合,且各个时间单位都只会出现一次。那如果将排列方式开放给调用方法的人,我们只需要将各个时间单位填进去,是不是就可以解决掉格式繁杂的问题?
export const formateDate = (
time: Date,
formate: string = 'Y年Mon月D日'
): string => {
let Y = time.getFullYear().toString();
let Mon = (time.getMonth() + 1).toString();
let D = time.getDate().toString();
let H = time.getHours().toString();
let Min = time.getMinutes().toString();
let S = time.getSeconds().toString();
Mon = parseInt(Mon) < 10 ? '0' + Mon : Mon
D = parseInt(D) < 10 ? '0' + D : D
H = parseInt(H) < 10 ? '0' + H : H
Min = parseInt(Min) < 10 ? '0' + Min : Min
S = parseInt(S) < 10 ? '0' + S : S
formate = formate.replace('Y', Y)
formate = formate.replace('Mon', Mon)
formate = formate.replace('D', D)
formate = formate.replace('H', H)
formate = formate.replace('Min', Min)
formate = formate.replace('S', S)
return formate
}
import { formateDate } from "./index";
console.log(formateDate(new Date(1672506061000), 'Y年Mon月D日 H时Min分S秒'));
//2023年01月01日 01时01分01秒
console.log(formateDate(new Date(1672506061000), 'Y-Mon-D H:Min:S'));
// 2023-01-04 14:00:20
这就是我们的最终版本,将时间格式的权利完全开放给了调用者,只要约定好格式的基本规则,就可以按照需求自由地返回想要的时间格式。
总结
日期格式处理器整体的代码并不复杂,相信谁都能看懂,谁都能做出来;只是我觉得在整个过程中,分析问题,抽象结构的过程很有意思。在日常写代码的过程中,任何一个细小的问题只要往后深究,往往也都有很多有意思的地方。
最后附上github和npm
npm i simple-date-formatter