前端利器DateUtils日期時(shí)間工具深度剖析
序言
在前端開(kāi)發(fā)中,日期和時(shí)間的處理是一個(gè)常見(jiàn)且重要的任務(wù)。從格式化日期展示到復(fù)雜的日期計(jì)算,每一個(gè)環(huán)節(jié)都需要精確和高效的代碼支持。今天,我們就來(lái)深入探討一個(gè)精心打造的前端日期時(shí)間工具類 DateUtils
,它涵蓋了從基礎(chǔ)的日期格式化到高級(jí)的日期范圍計(jì)算等一系列實(shí)用功能。
一、工具類概述
DateUtils
是一個(gè)功能豐富的日期時(shí)間工具集合,它為開(kāi)發(fā)者提供了便捷的方式來(lái)處理各種日期和時(shí)間相關(guān)的操作。該工具類依賴于一個(gè)輔助工具 TypeUtils
中的 isDate
方法來(lái)進(jìn)行日期對(duì)象的有效性驗(yàn)證。通過(guò)枚舉定義了多種常見(jiàn)的日期格式,并且提供了一系列方法來(lái)實(shí)現(xiàn)日期的格式化、解析、相對(duì)時(shí)間獲取、日期范圍計(jì)算、日期加減、差值計(jì)算等功能。
二、核心功能解析
(一)日期格式化
- FORMAT 枚舉
DateUtils
首先定義了一個(gè)FORMAT
枚舉,它包含了多種常用的日期格式,如DATE
(YYYY - MM - DD
)、TIME
(HH:mm:ss
)、DATETIME
(YYYY - MM - DD HH:mm:ss
)等,涵蓋了中文和英文的常見(jiàn)格式,方便開(kāi)發(fā)者在不同場(chǎng)景下選擇合適的格式。 - format 方法
format(date: Date, format: string = this.FORMAT.DATETIME): string { if (!TypeUtils.isDate(date)) { throw new Error("無(wú)效的日期對(duì)象!"); } const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); const hours = date.getHours(); const minutes = date.getMinutes(); const seconds = date.getSeconds(); return format .replace("YYYY", year.toString()) .replace("MM", month.toString().padStart(2, "0")) .replace("DD", day.toString().padStart(2, "0")) .replace("HH", hours.toString().padStart(2, "0")) .replace("mm", minutes.toString().padStart(2, "0")) .replace("ss", seconds.toString().padStart(2, "0")); }
該方法接收一個(gè) Date
對(duì)象和一個(gè)可選的格式字符串作為參數(shù)。如果未傳入格式字符串,則默認(rèn)使用 DATETIME
格式。首先通過(guò) TypeUtils.isDate
方法驗(yàn)證日期對(duì)象的有效性,然后從 Date
對(duì)象中提取年、月、日、時(shí)、分、秒等信息,最后通過(guò)字符串替換的方式將占位符替換為實(shí)際的日期時(shí)間值,實(shí)現(xiàn)日期的格式化。
(二)日期解析
parse
方法用于將日期字符串解析為 Date
對(duì)象。
parse(dateStr: string): Date { const date = new Date(dateStr); if (isNaN(date.getTime())) { throw new Error("無(wú)效的日期字符串!"); } return date; }
該方法嘗試使用 Date
構(gòu)造函數(shù)將傳入的字符串解析為日期對(duì)象。如果解析后的日期對(duì)象的 getTime
方法返回 NaN
,則說(shuō)明解析失敗,拋出“無(wú)效的日期字符串!”錯(cuò)誤。
(三)相對(duì)時(shí)間獲取
getRelativeTime
方法用于獲取相對(duì)于當(dāng)前時(shí)間的日期描述。
getRelativeTime(date: Date): string { const now = new Date(); const diff = now.getTime() - date.getTime(); const minutes = Math.floor(diff / (1000 * 60)); const hours = Math.floor(diff / (1000 * 60 * 60)); const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (minutes < 1) return "剛剛"; if (minutes < 60) return `${minutes}分鐘前`; if (hours < 24) return `${hours}小時(shí)前`; if (days < 30) return `${days}天前`; return this.format(date, this.FORMAT.DATE); }
該方法首先計(jì)算當(dāng)前時(shí)間與傳入日期之間的時(shí)間差,然后根據(jù)時(shí)間差的大小返回不同的相對(duì)時(shí)間描述。如果時(shí)間差小于 1 分鐘,返回“剛剛”;如果小于 60 分鐘,返回“X 分鐘前”;如果小于 24 小時(shí),返回“X 小時(shí)前”;如果小于 30 天,返回“X 天前”;否則,返回格式化后的日期字符串。
(四)日期范圍獲取
getDateRange
方法用于獲取指定類型(周、月、年)的日期范圍。
getDateRange(type: "week" | "month" | "year"): [Date, Date] { const now = new Date(); let start: Date, end: Date; switch (type) { case "week": const day = now.getDay() || 7; start = new Date(now.setDate(now.getDate() - day + 1)); end = new Date(now.setDate(now.getDate() + 6)); break; case "month": start = new Date(now.getFullYear(), now.getMonth(), 1); end = new Date(now.getFullYear(), now.getMonth() + 1, 0); break; case "year": start = new Date(now.getFullYear(), 0, 1); end = new Date(now.getFullYear(), 11, 31); break; } return [start, end]; }
該方法根據(jù)傳入的類型參數(shù),通過(guò) switch
語(yǔ)句分別計(jì)算本周、本月、本年的起止日期。例如,對(duì)于“week”類型,先獲取當(dāng)前日期是一周中的第幾天(周日為 0,這里處理為 7),然后計(jì)算本周的起始日期和結(jié)束日期。
(五)日期加減
add
方法用于對(duì)日期進(jìn)行加減操作。
add( date: Date, amount: number, unit: "year" | "month" | "day" | "hour" | "minute" | "second" ): Date { const result = new Date(date); switch (unit) { case "year": result.setFullYear(result.getFullYear() + amount); break; case "month": result.setMonth(result.getMonth() + amount); break; case "day": result.setDate(result.getDate() + amount); break; case "hour": result.setHours(result.getHours() + amount); break; case "minute": result.setMinutes(result.getMinutes() + amount); break; case "second": result.setSeconds(result.getSeconds() + amount); break; } return result; }
該方法接收一個(gè) Date
對(duì)象、一個(gè)數(shù)值和一個(gè)時(shí)間單位作為參數(shù)。通過(guò) switch
語(yǔ)句根據(jù)不同的時(shí)間單位,對(duì)日期對(duì)象進(jìn)行相應(yīng)的加減操作,并返回新的日期對(duì)象。
(六)日期差值計(jì)算
diff
方法用于計(jì)算兩個(gè)日期之間的差值。
diff( date1: Date, date2: Date, unit: "year" | "month" | "day" | "hour" | "minute" | "second" ): number { const diff = date2.getTime() - date1.getTime(); switch (unit) { case "year": return date2.getFullYear() - date1.getFullYear(); case "month": return ( (date2.getFullYear() - date1.getFullYear()) * 12 + date2.getMonth() - date1.getMonth() ); case "day": return Math.floor(diff / (1000 * 60 * 60 * 24)); case "hour": return Math.floor(diff / (1000 * 60 * 60)); case "minute": return Math.floor(diff / (1000 * 60)); case "second": return Math.floor(diff / 1000); default: return diff; } }
該方法接收兩個(gè) Date
對(duì)象和一個(gè)時(shí)間單位作為參數(shù)。首先計(jì)算兩個(gè)日期的時(shí)間戳差值,然后根據(jù)不同的時(shí)間單位,通過(guò) switch
語(yǔ)句進(jìn)行相應(yīng)的計(jì)算,返回兩個(gè)日期之間的差值。
(七)工作日判斷
isWorkday
方法用于判斷一個(gè)日期是否為工作日。
isWorkday(date: Date): boolean { const day = date.getDay(); return day!== 0 && day!== 6; }
該方法通過(guò)獲取日期是一周中的第幾天(周日為 0,周六為 6),判斷該日期是否既不是周日也不是周六,從而確定是否為工作日。
(八)月份天數(shù)獲取
getDaysInMonth
方法用于獲取指定月份的天數(shù)。
getDaysInMonth(year: number, month: number): number { return new Date(year, month, 0).getDate(); }
該方法通過(guò)創(chuàng)建一個(gè)指定年份和月份的 Date
對(duì)象,并將日期設(shè)置為 0,此時(shí) getDate
方法返回的就是該月份的總天數(shù)。
(九)閏年判斷
isLeapYear
方法用于判斷指定年份是否為閏年。
isLeapYear(year: number): boolean { return (year % 4 === 0 && year % 100!== 0) || year % 400 === 0; }
該方法根據(jù)閏年的定義,即能被 4 整除且不能被 100 整除,或者能被 400 整除的年份為閏年,返回相應(yīng)的布爾值。
(十)獲取日期是當(dāng)年的第幾周
getWeekOfYear
方法用于獲取指定日期是當(dāng)年的第幾周。
getWeekOfYear(date: Date): number { const start = new Date(date.getFullYear(), 0, 1); const diff = date.getTime() - start.getTime() + (start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000; const oneWeek = 1000 * 60 * 60 * 24 * 7; return Math.floor(diff / oneWeek) + 1; }
該方法首先獲取當(dāng)年的第一天,然后計(jì)算指定日期與當(dāng)年第一天的時(shí)間差,并考慮了時(shí)區(qū)偏移量。最后將時(shí)間差除以一周的毫秒數(shù),并向上取整加 1,得到該日期是當(dāng)年的第幾周。
(十一)獲取時(shí)間戳
getTimestamp
方法用于獲取指定日期的時(shí)間戳,如果未傳入日期,則返回當(dāng)前日期的時(shí)間戳。
getTimestamp(date: Date = new Date()): number { return date.getTime(); }
該方法通過(guò)調(diào)用 Date
對(duì)象的 getTime
方法獲取時(shí)間戳。
三. 工具類功能詳解
(一) 日期格式化
方法說(shuō)明:format
方法用于將Date
對(duì)象格式化為指定的字符串格式。它支持多種預(yù)定義的格式,如YYYY-MM-DD
、HH:mm:ss
等,也支持自定義格式字符串。
使用示例:
const date = new Date('2024-03-21 14:30:00'); DateUtils.format(date); // "2024-03-21 14:30:00" DateUtils.format(date, DateUtils.FORMAT.DATE); // "2024-03-21" DateUtils.format(date, DateUtils.FORMAT.DATE_CN); // "2024年03月21日" DateUtils.format(date, 'YYYY/MM/DD'); // "2024/03/21"
(二)日期解析
方法說(shuō)明:parse
方法用于將日期字符串解析為Date
對(duì)象。無(wú)論是標(biāo)準(zhǔn)的ISO格式還是中文格式,都可以輕松解析。
使用示例:
DateUtils.parse('2024-03-21'); // Date 對(duì)象 DateUtils.parse('2024-03-21 14:30:00'); // Date 對(duì)象 DateUtils.parse('2024年03月21日'); // Date 對(duì)象
(三)相對(duì)時(shí)間描述
方法說(shuō)明:getRelativeTime
方法可以根據(jù)當(dāng)前時(shí)間生成相對(duì)時(shí)間描述,如“剛剛”、“5分鐘前”、“2小時(shí)前”等。
使用示例:
const date = new Date('2024-03-21 14:30:00'); DateUtils.getRelativeTime(date); // "剛剛"、"5分鐘前"、"2小時(shí)前"、"3天前"等
(四) 日期范圍獲取
方法說(shuō)明:getDateRange
方法可以方便地獲取本周、本月、今年的起止日期。
使用示例:
// 獲取本周的起止日期 const [weekStart, weekEnd] = DateUtils.getDateRange('week'); // 獲取本月的起止日期 const [monthStart, monthEnd] = DateUtils.getDateRange('month'); // 獲取今年的起止日期 const [yearStart, yearEnd] = DateUtils.getDateRange('year');
(五)日期加減
方法說(shuō)明:add
方法支持對(duì)日期進(jìn)行加減操作,支持年、月、日、時(shí)、分、秒等多種單位。
使用示例:
const date = new Date('2024-03-21'); // 加一天 DateUtils.add(date, 1, 'day'); // 返回 2024-03-22 // 減一個(gè)月 DateUtils.add(date, -1, 'month'); // 返回 2024-02-21 // 加一年 DateUtils.add(date, 1, 'year'); // 返回 2025-03-21
(六)日期差值計(jì)算
方法說(shuō)明:diff
方法可以計(jì)算兩個(gè)日期之間的差值,支持年、月、日、時(shí)、分、秒等多種單位。
使用示例:
const date1 = new Date('2024-03-21'); const date2 = new Date('2024-03-25'); DateUtils.diff(date1, date2, 'day'); // 返回 4 DateUtils.diff(date1, date2, 'hour'); // 返回 96
(七) 工作日判斷
方法說(shuō)明:isWorkday
方法可以判斷某個(gè)日期是否為工作日(周一至周五)。
使用示例:
const date = new Date('2024-03-21'); DateUtils.isWorkday(date); // 返回 true (周四) DateUtils.isWorkday(new Date('2024-03-23')); // 返回 false (周六)
(八) 獲取月份天數(shù)
方法說(shuō)明:getDaysInMonth
方法可以獲取指定年份和月份的天數(shù),支持閏年判斷。
使用示例:
DateUtils.getDaysInMonth(2024, 2); // 返回 29 (閏年2月) DateUtils.getDaysInMonth(2024, 3); // 返回 31
(九) 閏年判斷
方法說(shuō)明:isLeapYear
方法可以判斷某一年是否為閏年。
使用示例:
DateUtils.isLeapYear(2024); // 返回 true DateUtils.isLeapYear(2023); // 返回 false
(十) 獲取日期是當(dāng)年的第幾周
方法說(shuō)明:getWeekOfYear
方法可以獲取某個(gè)日期是當(dāng)年的第幾周。
使用示例:
DateUtils.getWeekOfYear(new Date('2024-03-21')); // 返回周數(shù)
(十一) 獲取時(shí)間戳
方法說(shuō)明:getTimestamp
方法可以獲取當(dāng)前時(shí)間或指定日期的時(shí)間戳。
使用示例:
DateUtils.getTimestamp(); // 返回當(dāng)前時(shí)間戳 DateUtils.getTimestamp(new Date('2024-03-21')); // 返回指定日期的時(shí)間戳
四、總結(jié)
DateUtils
工具類為前端開(kāi)發(fā)者提供了一個(gè)全面且強(qiáng)大的日期時(shí)間處理解決方案。無(wú)論是在數(shù)據(jù)展示、數(shù)據(jù)分析還是業(yè)務(wù)邏輯處理中,這些功能都能極大地提高開(kāi)發(fā)效率,減少日期時(shí)間處理過(guò)程中的錯(cuò)誤。通過(guò)合理運(yùn)用這些方法,開(kāi)發(fā)者可以更加專注于業(yè)務(wù)邏輯的實(shí)現(xiàn),而無(wú)需在基礎(chǔ)的日期時(shí)間操作上花費(fèi)過(guò)多精力。希望本文對(duì) DateUtils
的剖析能幫助你更好地理解和運(yùn)用這個(gè)工具類,在前端開(kāi)發(fā)中更加得心應(yīng)手地處理日期和時(shí)間相關(guān)的任務(wù)。
到此這篇關(guān)于前端利器DateUtils日期時(shí)間工具的文章就介紹到這了,更多相關(guān)前端DateUtils日期時(shí)間內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談JavaScript變量的自動(dòng)轉(zhuǎn)換和語(yǔ)句
下面小編就為大家?guī)?lái)一篇淺談JavaScript變量的自動(dòng)轉(zhuǎn)換和語(yǔ)句。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06JS事件監(jiān)聽(tīng)與事件委托舉例詳解(前端小白必學(xué))
在JavaScript的學(xué)習(xí)中我們經(jīng)常會(huì)遇到JavaScript的事件機(jī)制,例如,事件綁定、事件監(jiān)聽(tīng)、事件委托(事件代理)等,下面這篇文章主要給大家介紹了關(guān)于JS事件監(jiān)聽(tīng)與事件委托的相關(guān)資料,需要的朋友可以參考下2024-07-07Windows下支持自動(dòng)更新的Electron應(yīng)用腳手架的方法
這篇文章主要介紹了Windows下支持自動(dòng)更新的Electron應(yīng)用腳手架的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12給頁(yè)面渲染時(shí)間加速 干掉Dom Level 0 Event
我們?nèi)サ羰录壎ǖ倪壿?發(fā)現(xiàn)只渲染dom元素,不綁定事件的時(shí)間,僅僅125ms,可見(jiàn)事件綁定的時(shí)間消耗還是很大的 ,尤其是第一種方式,也就是Dom Level 0 Event,最為耗時(shí)2012-12-12javascript與css3動(dòng)畫(huà)結(jié)合使用小結(jié)
本文給大家講述的是如何使用javascript結(jié)合CSS動(dòng)畫(huà)來(lái)實(shí)現(xiàn)一些占用資源更少,更優(yōu)化的動(dòng)畫(huà)效果,思路十分巧妙,這里推薦給小伙伴們參考下。2015-03-03js實(shí)現(xiàn)動(dòng)畫(huà)特效的文字鏈接鼠標(biāo)懸停提示的方法
這篇文章主要介紹了js實(shí)現(xiàn)動(dòng)畫(huà)特效的文字鏈接鼠標(biāo)懸停提示的方法,實(shí)例分析了javascript操作css的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03