偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

前端日期處理,為什么不要用 Date 構(gòu)造函數(shù)?

開發(fā) 前端
如果我們?cè)弧叭掌诳偸遣钜惶臁?、“本地和服?wù)器時(shí)間對(duì)不上”、“月份為什么從0開始”等問(wèn)題折磨過(guò),那么我們可能已經(jīng)體會(huì)到了原生 Date 對(duì)象的“險(xiǎn)惡”。

在 JavaScript 的世界里,時(shí)間與日期處理是一個(gè)繞不開的話題。從顯示文章發(fā)布時(shí)間,到計(jì)算活動(dòng)倒計(jì)時(shí),再到處理復(fù)雜的時(shí)區(qū)轉(zhuǎn)換,我們總會(huì)與日期打交道。而 JS 的內(nèi)置 Date 對(duì)象,似乎是理所當(dāng)然的第一選擇。

然而,如果我們?cè)弧叭掌诳偸遣钜惶臁?、“本地和服?wù)器時(shí)間對(duì)不上”、“月份為什么從0開始”等問(wèn)題折磨過(guò),那么我們可能已經(jīng)體會(huì)到了原生 Date 對(duì)象的“險(xiǎn)惡”。

一、Date 對(duì)象的“三宗罪”

1. 不可靠的字符串解析

這是 Date 對(duì)象最致命、最廣為人知的缺陷。new Date(dateString) 的行為在不同瀏覽器和不同日期格式下,表現(xiàn)得像一個(gè)捉摸不定的“渣男”。

看這個(gè)經(jīng)典的例子:

// 格式一:YYYY-MM-DD
const date1 = new Date('2025-07-15'); 
// 在多數(shù)現(xiàn)代瀏覽器中,這會(huì)被解析為 UTC 時(shí)間的零點(diǎn):
// "Tue Jul 15 2025 08:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"

// 格式二:YYYY/MM/DD
const date2 = new Date('2025/07/15');
// 這通常會(huì)被解析為本地時(shí)間的零點(diǎn):
// "Tue Jul 15 2025 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"

發(fā)現(xiàn)問(wèn)題了嗎?

僅僅是分隔符 - 和 / 的區(qū)別,new Date() 的解析策略就完全不同。前者(YYYY-MM-DD)被當(dāng)作 UTC 時(shí)間,而后者(YYYY/MM/DD)被當(dāng)作本地時(shí)間。

這在處理只有日期的字符串時(shí)是災(zāi)難性的。假設(shè)后端傳來(lái)一個(gè) 2025-07-15,代表某人的生日。我們用 new Date() 解析后,如果用戶在西半球,獲取日期時(shí)可能會(huì)得到 2025/07/15,憑空少了一天!這種因時(shí)區(qū)差異導(dǎo)致的不確定性,是許多線上 Bug 的根源。

結(jié)論:永遠(yuǎn)不要相信 new Date(dateString) 能穩(wěn)定、跨瀏覽器地解析我們傳入的字符串。

2. 對(duì)象的可變性(Mutability)

Date 對(duì)象是可變的(mutable)。這意味著一旦創(chuàng)建,它的值可以被任意修改。這在復(fù)雜的業(yè)務(wù)邏輯中,很容易導(dǎo)致難以追蹤的副作用。

想象一個(gè)場(chǎng)景:

在上面的函數(shù)中,我們本意是想根據(jù) today 計(jì)算出 tomorrow,但由于直接修改了 today 對(duì)象,導(dǎo)致原始的 today 變量也被污染了。如果 today 在代碼的其他地方還需要使用,問(wèn)題就大了。

一個(gè)健壯的日期處理方式應(yīng)該是不可變的(immutable),即任何操作都返回一個(gè)新的日期對(duì)象,而不是修改原始對(duì)象。

3. API 設(shè)計(jì)

Date 對(duì)象的 API 設(shè)計(jì)充滿了各種反直覺:

  • 月份從 0 開始:getMonth() 返回 0 代表一月,11 代表十二月。這是新手最常犯的錯(cuò)誤。new Date(2025, 7, 15) 創(chuàng)建的是八月二十六日,而不是七月
  • 獲取年份的方法不統(tǒng)一:雖然現(xiàn)在我們都用 getFullYear(),但歷史上還存在一個(gè) getYear(),它在某些瀏覽器和年份下返回的是“年份減去1900”的結(jié)果
  • 格式化能力為零:想把日期格式化成 YYYY-MM-DD HH:mm:ss?對(duì)不起,原生 Date 沒有提供直接的方法。我們必須手動(dòng) getFullYear(), getMonth()+1, getDate()… 然后自己拼字符串,還要處理數(shù)字前補(bǔ)零的問(wèn)題
  • 復(fù)雜的日期計(jì)算:計(jì)算“30天后”或者“下個(gè)月的今天”?我們需要小心翼翼地使用 setDate() 和 setMonth(),并處理好跨月份、跨年份的邊界情況

這些設(shè)計(jì)缺陷大大降低了開發(fā)效率,并增加了出錯(cuò)的可能性。

二、正確的姿勢(shì):擁抱現(xiàn)代日期庫(kù)

既然原生 Date 如此不堪,我們?cè)撛趺崔k?答案很簡(jiǎn)單:使用一個(gè)成熟、可靠的第三方日期庫(kù)。

這并非“重復(fù)造輪子”,而是站在巨人的肩膀上,讓我們專注于業(yè)務(wù)邏輯,而不是和底層的怪癖作斗爭(zhēng)。

目前社區(qū)主流的選擇有:

1. Day.js (強(qiáng)烈推薦)

優(yōu)點(diǎn):體積小巧(壓縮后僅 2KB),API 設(shè)計(jì)與曾經(jīng)的王者 Moment.js 極其相似,學(xué)習(xí)成本低。它支持鏈?zhǔn)秸{(diào)用,代碼寫起來(lái)非常流暢。

特點(diǎn):默認(rèn)不可變(需要插件支持,但強(qiáng)烈建議使用)、功能通過(guò)插件體系擴(kuò)展(按需加載)。

看看用 Day.js 如何解決上面的問(wèn)題:

import dayjs from 'dayjs';

// 1. 可靠的解析
const date = dayjs('2025-07-15'); // 無(wú)論什么格式,解析行為都穩(wěn)定一致

// 2. 不可變性
const today = dayjs();
const tomorrow = today.add(1, 'day'); // .add() 返回一個(gè)新的 dayjs 對(duì)象

console.log(today.format());    // 原始對(duì)象不變
console.log(tomorrow.format()); // 新的對(duì)象

// 3. 優(yōu)雅的 API
// 格式化
console.log(dayjs().format('YYYY-MM-DD HH:mm:ss')); // "2025-07-15 15:30:00"

// 獲取月份 (從 1 開始)
console.log(dayjs().month() + 1); 

// 計(jì)算
console.log(dayjs().add(7, 'day').format('YYYY-MM-DD')); // 7天后
console.log(dayjs().subtract(1, 'month').format('YYYY-MM-DD')); // 1個(gè)月前

代碼是不是瞬間變得清晰、健壯、且易于維護(hù)了?

2. 未來(lái)的希望:Temporal API

值得一提的是,JavaScript 自身也在進(jìn)化。新的 Temporal API 旨在從根本上取代 Date 對(duì)象,提供一個(gè)全新的、設(shè)計(jì)精良的日期/時(shí)間處理方案。它內(nèi)置了不可變性、無(wú)歧義的 API 和完善的時(shí)區(qū)支持。

雖然目前還需要 Polyfill 才能使用,但它代表了 JS 日期處理的未來(lái)。

三、什么時(shí)候可以用 new Date()?

說(shuō)了這么多,是不是原生 Date 就一無(wú)是處了?也不是。在一些極其簡(jiǎn)單的場(chǎng)景下,它仍然可用:獲取當(dāng)前時(shí)間戳、傳遞給日期庫(kù)、非關(guān)鍵性、無(wú)解析需求的場(chǎng)景。

但對(duì)于任何需要解析后端返回的日期字符串、進(jìn)行日期計(jì)算、或者需要格式化顯示的業(yè)務(wù)場(chǎng)景,建議借助第三方庫(kù)。

這幾 KB 的庫(kù)體積,換來(lái)的是代碼的穩(wěn)定性、可維護(hù)性,以及讓我們從日期處理的泥潭中解放出來(lái)的寶貴時(shí)間。

責(zé)任編輯:趙寧寧 來(lái)源: JavaScript
相關(guān)推薦

2025-07-31 04:00:00

前端JavaScriptDate

2015-06-04 11:22:22

前端程序員

2015-06-05 11:23:19

前端為什么不要你

2022-03-29 09:03:22

測(cè)試組件Propsrender

2009-01-09 23:06:41

服務(wù)器SCSI硬盤PC

2018-11-29 11:18:11

VLANVPC數(shù)據(jù)中心

2020-04-07 16:12:56

Go編程語(yǔ)言開發(fā)

2019-09-04 09:31:40

日志Flink監(jiān)控

2023-06-29 18:08:41

2024-07-02 13:27:38

2021-05-11 06:57:15

HBaseBATJ公司

2021-12-13 01:40:29

ElasticSear倒排索引

2024-01-02 17:28:12

芯片CPUAI計(jì)算

2022-05-07 07:35:44

工具讀寫鎖Java

2015-07-01 10:25:07

Docker開源項(xiàng)目容器

2023-09-22 10:05:32

2022-07-06 09:29:40

JMH性能測(cè)試

2016-01-12 16:58:31

C游戲

2017-02-16 07:37:19

前端程序軟件

2024-12-09 09:00:00

拷貝構(gòu)造函數(shù)傳遞編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)