2024/02/29 到職的同事,2027 年的週年日是哪一天?2027 年沒有 2/29,公式會給你 2/28 還是 3/1?答案看你用哪個函式。
DATE、EDATE、DATEDIF 的語法在 日期與時間入門 和 日期計算實戰 講過了,這篇只挑會出事的地方,從 2/29、月底、季末,一路看到 DATEDIF 的 "MD"、週末字串、補班日,最後是 TODAY 為什麼同一格每天都不一樣。
DATE 的年份小於 1900
入門篇提過 DATE 的年份 0 到 1899 會被加上 1900。這個規則害人的方式有三種:
| 公式 | 結果 | 發生什麼事 |
|---|---|---|
| 3799/12/30 | 想找序號 0 那天,結果跑到 1899 加 1900 | |
| 1926/10/11 | 兩位數的年份變成 19xx | |
| 2015/10/11 | 民國 115 年被當成 115 加 1900 |
民國年的那一列最危險,因為 2015 是個合理的日期,不會報錯,只會悄悄算錯。民國年要先加 1911: 才是 2026/10/11。
序號 0 那天是 1899/12/30,用 DATE 組不出來。想看到 0,可以用 ,1900/01/01 的序號是 2,減 2 就是 0。
另外一個小技巧,日填 0 會退到上個月的最後一天: 預期得到 2026/10/31。這是 EOMONTH 出現之前常見的月底寫法,我現在還是比較習慣直接用 EOMONTH。
2/29 的週年
資料放這樣,到職日在 B2,基準日在 E1,這邊假設今天是 2026/10/11:
| B | E | |
|---|---|---|
| 1 | 到職日 | 基準日 |
| 2 | 2024/02/29 | 2026/10/11 |
我想列出之後每年的週年日,有兩種寫法。一種是自己拼:,另一種是 ,n 是第幾年。來看看結果:
| 週年 | DATE(年,2,29) | EDATE($B$2,12*n) |
|---|---|---|
| 第 1 年(2025) | 2025/03/01 | 2025/02/28 |
| 第 2 年(2026) | 2026/03/01 | 2026/02/28 |
| 第 3 年(2027) | 2027/03/01 | 2027/02/28 |
| 第 4 年(2028) | 2028/02/29 | 2028/02/29 |
2025 年沒有 2/29,DATE 的做法是日期溢出,往後進位成 3/1。EDATE 則是夾回該月的最後一天,變成 2/28。到了 2028 年,兩個都回到 2/29。
要選哪個,其實是公司規則:閏日出生的人,平年的生日要過 2/28 還是 3/1?我個人偏好 EDATE,因為它永遠落在同一個月,月份不會跳掉。
還有一個更容易犯的錯,是一年一年往後推:
連推四次,每次加 12 個月
=EDATE(EDATE(EDATE(EDATE(B2,12),12),12),12)結果是 2028/02/28,不是 2028/02/29。第一次推到 2025/02/28 之後,日子就掉成 28 了,後面再推都是 28。一律從原始日期推,月數用 12 乘以年數,也就是上表右邊那種寫法。
下一個週年日怎麼算?先用 DATEDIF 算出已經滿幾年,加 1 再丟進 EDATE:
下一個週年日
=EDATE(B2, 12*(DATEDIF(B2, E1, "Y")+1))滿 2 年,所以是 EDATE(B2,36),結果 2027/02/28。
DATEDIF 對 2/29 的看法是 2025/02/28 還沒滿 1 年,2025/03/01 才滿: 是 0, 是 1。這和上面 EDATE 的 2/28 並不一致,所以同一份名單裡,「滿週年」和「週年日」最好用同一套邏輯,不要混著用。
月底連續推算
同一個問題換成月底。合約簽在 2026/01/31,我想列出每個月的付款日:
| 月數 | 一個月一個月累加 | 從 B2 直接推 |
|---|---|---|
| 1 | 2026/02/28 | 2026/02/28 |
| 2 | 2026/03/28 | 2026/03/31 |
| 3 | 2026/04/28 | 2026/04/30 |
| 4 | 2026/05/28 | 2026/05/31 |
左邊是 往下填,右邊是 。左邊被 2 月夾成 28 之後就回不去了。原因跟 2/29 一樣,一律從原始日期推。
如果合約本來就是「每月月底付款」,直接用 EOMONTH,不用管 28、30、31:
簽約月往後 2 個月的月底
=EOMONTH(B2, 2)結果是 2026/03/31。
帶時間的資料
篩「這個月」的資料,常寫成大於等於月初、小於等於月底。資料如果帶時間,月底那天會少算。下單時間放在 A2:A7:
| A | |
|---|---|
| 1 | 下單時間 |
| 2 | 2026/10/01 09:15 |
| 3 | 2026/10/12 18:40 |
| 4 | 2026/10/30 16:20 |
| 5 | 2026/10/31 14:30 |
| 6 | 2026/10/31 23:05 |
| 7 | 2026/11/01 08:10 |
D1 放月初 ,D2 放月底 。10 月的單明明有 5 筆,這樣數:
小於等於月底,當天的時間被排除
=COUNTIFS(A2:A7, ">="&D1, A2:A7, "<="&D2)結果是 3。EOMONTH 回傳的是 10/31 00:00,所以 10/31 14:30 和 23:05 都比它晚,被排掉了。改成小於「月底加 1」,也就是下個月的月初:
小於下個月月初,整個月底都算進去
=COUNTIFS(A2:A7, ">="&D1, A2:A7, "<"&(D2+1))結果是 5。COUNTIFS 的條件寫法在 SUMIFS 進階陷阱 有講。
季初與季末
季末不用判斷一年四季,用 MOD 算出「離季末還差幾個月」就好:
這個日期所在季的最後一天
=EOMONTH(B2, MOD(3-MONTH(B2), 3))10 月:MOD(3-10,3) 是 MOD(-7,3),在 Sheets 的結果是 2,所以往後推 2 個月,12 月底。季初則是先退回季末的前一季,再加 1 天:
這個日期所在季的第一天
=EOMONTH(B2, MOD(3-MONTH(B2), 3)-3)+1用幾個日期試試看:
| 日期 | 季初 | 季末 |
|---|---|---|
| 2026/10/11 | 2026/10/01 | 2026/12/31 |
| 2026/11/30 | 2026/10/01 | 2026/12/31 |
| 2026/12/31 | 2026/10/01 | 2026/12/31 |
| 2026/03/15 | 2026/01/01 | 2026/03/31 |
| 2026/01/01 | 2026/01/01 | 2026/03/31 |
| 2026/05/02 | 2026/04/01 | 2026/06/30 |
季末當天(12/31、3/31)MOD 是 0,推 0 個月,還是自己所在的季。要「本季」就把 B2 換成 TODAY(),不過寫報表的時候,我會把 TODAY() 放在一格設定,其他公式去參照它,原因在最後一節。
DATEDIF 的 MD
DATEDIF 的 "MD" 單位,意思是扣掉整年整月之後剩下的天數。Microsoft 在 Excel 的 DATEDIF 說明裡建議不要用 "MD",說有已知的限制,可能算出負數或不對的數字。Sheets 這邊我找不到對應的官方說明,不過實際算下來,它真的會出現負數,這個單位的名聲不太好是有原因的。
最容易出怪結果的是起日在月底、終點月比較短的組合。拿 2026/01/31 到 2026/03/01 來看,直覺答案是「1 個月又 1 天」。"M" 是 1,"MD" 卻會算出 -2,不是 1,也不是任何看得出道理的天數。
我自己的做法是不用 "MD",先算滿幾個月,再用 EDATE 算出那一天,最後相減:
滿整月之後剩下的天數
=C2 - EDATE(B2, DATEDIF(B2, C2, "M"))B2 是 2026/01/31、C2 是 2026/03/01 的話,滿 1 個月的那天是 EDATE(B2,1),也就是 2026/02/28,3/1 減掉它剩 1 天。
另外一個陷阱,開始日比結束日晚,DATEDIF 預期會回 #NUM!,不像 NETWORKDAYS 會回負數。報表裡如果結束日可能是空的或比較早,先用 IF 擋一下。
週末字串
NETWORKDAYS 和 WORKDAY 的週末固定是六、日。公司週日單休、週六要上班的話,改用 NETWORKDAYS.INTL 和 WORKDAY.INTL,多一個週末參數:
週末可以填數字代碼,也可以填 7 個字元的字串。字串從週一排到週日,1 是休息、0 是上班。預設的週六日是 "0000011",週日單休是 "0000001"。
資料這樣放:開始日 B2 是 2026/10/01(週四),結束日 C2 是 2026/10/31(週六),假日放在 H2:H3,示範用 2026/10/09 和 2026/10/10。實際放假日請以人事行政總處的公告為準。
| 週末設定 | 假日 | 工作日數 |
|---|---|---|
"0000011"(週六日休) | 有 | 21 |
"0000001"(週日單休) | 無 | 27 |
"0000001"(週日單休) | 有 | 25 |
"0000000"(天天上班) | 無 | 31 |
週日單休的時候,國慶日 10/10 剛好是週六,這次它不再被週末排掉,所以假日清單要扣 2 天:27 變 25。同樣的假日在週六日休的設定下,10/10 已經是週末,只會多扣 10/9 一天。
數字代碼也可以:11 是「只有週日休」,所以 NETWORKDAYS.INTL(B2,C2,11,H2:H3) 的結果和 "0000001" 一樣是 25。
漏了引號
這是最容易中的坑。字串一定要有引號:
漏了引號的寫法
=NETWORKDAYS.INTL(B2, C2, 0000001, H2:H3)沒有引號,0000001 會被當成數字 1,開頭的零不見了,而代碼 1 就是預設的週六日休。結果預期是 21,不會報錯,只是悄悄用錯了週末。看到週末字串,先確認有沒有引號。
WORKDAY.INTL
WORKDAY.INTL(開始日, 天數, [週末], [假日]) 的週末參數同理。從 2026/10/01 起算 10 個工作日,週日單休、扣掉 H2:H3:
週日單休,往後 10 個工作日
=WORKDAY.INTL(DATE(2026,10,1), 10, "0000001", H2:H3)結果是 2026/10/15。手算一下:10/2 週五是第 1 天,10/3 週六第 2 天,10/5 到 10/8 是第 3 到 6 天,10/9 和 10/10 放假跳過,10/12 到 10/15 是第 7 到 10 天。
沒有假日清單的話,是 2026/10/13。同樣的 10 天,用預設的 WORKDAY(週六日休)加上假日清單,結果是 2026/10/16。
假日範圍與補班日
假日清單的範圍有兩件事要注意。
第一,裡面要是真的日期。如果是 TEXT 做出來的「2026/10/09」文字,NETWORKDAYS 會直接回 #VALUE!,不是默默不扣。清單換成真正的日期值(例如 DATE(2026,10,9)),結果才會是扣掉 10/9 的 21 天。拿 ISNUMBER 檢查一下清單,比較保險。
第二,台灣有補班日,週六要上班。NETWORKDAYS 沒有「例外上班」的參數,得自己加回去。補班日放在 J2:J3,示範假設 2026/10/17(週六)要補班:
工作日數,加上落在期間內的補班日
=NETWORKDAYS(B2, C2, H2:H3) + COUNTIFS(J2:J3, ">="&B2, J2:J3, "<="&C2)預設週六日休的 10 月是 21 天,加上那一個補班日,結果是 22。補班日必須是週末,而且不要同時寫進假日清單,不然就抵銷了。
TODAY 讓結果每天都變
TODAY 每天都是新的值。這件事在報表上會有點尷尬,我拿一位到職日 2022/08/01 的員工(放在 B2)來看,年資公式是:
年資寫成 X年Y個月
=DATEDIF(B2, E1, "Y") & "年" & DATEDIF(B2, E1, "YM") & "個月"E1 放不同的基準日,結果就不一樣:
E1(基準日) | 結果 |
|---|---|
| 2026/10/11 | 4年2個月 |
| 2026/11/11 | 4年3個月 |
| 2027/03/01 | 4年7個月 |
如果 E1 放的是 ,上個月存起來的報表,這個月打開,數字就變了。所以我的習慣:
- 需要「即時」的儀表板,
E1放 ,其他公式都參照E1,不要每條公式各放一個TODAY()。 - 需要「存檔」的報表,把
E1換成固定日期。快速打入今天日期的快捷鍵,在 Chrome 上 Windows 是 Ctrl+;,Mac 是 Cmd+;,輸入後是固定的值,不會再變。 - 已經算好的結果要凍起來,複製後用 Ctrl+Shift+V(Mac 是 Cmd+Shift+V)貼上值。
還有一個小地方,TODAY 的「今天」是依試算表自己的時區,而不是你電腦的時區。跨時區共用的檔案,開出來的日期可能差一天,時區設定在「檔案」>「設定」裡看。
練習
找出錯在哪
同事要算 2026/10/01 到 2026/10/31 的工作日,公司週日單休,假日放在 H2:H3(2026/10/09 與 2026/10/10)。他寫了 ,算出 21,可是週六也要上班,答案應該更多。錯在哪裡?正確答案是多少?
日期的坑大多是同一種:先想清楚「2/29 要算 2/28 還是 3/1」「月底那天算不算」這種規則,再選函式,公式才不會被 2 月打到。
我是喜特先生,Mr. Sheet,我們下個教學見!
接下來可以
這篇在技能樹的 Lv.4「進階應用」,模組「進階日期處理」(第 1/1 篇)。讀完這篇,路線上的下一個模組是「進階資料處理」。
回到技能樹相關文章
查看所有文章日期與時間入門:日期序號、DATE、TODAY 與文字日期
從日期序號開始,認識 DATE、TODAY、NOW、YEAR、MONTH、DAY,學會日期加減、分辨文字日期和真日期,並搞清楚顯示格式和儲存格的值是兩回事。
年資、工作日、到期日:日期計算實戰
用 DATEDIF 算員工年資,用 NETWORKDAYS 和 WORKDAY 搭配假日清單算工作日,再用 EDATE 和 EOMONTH 算合約到期日與月底結帳日。
SUMIFS 進階陷阱:多條件、日期區間、萬用字元與 MAXIFS
整理 SUMIFS、COUNTIFS 多條件加總常踩的坑:參數順序和 SUMIF 相反、範圍大小不一致、日期區間與文字日期、OR 條件重複計算、萬用字元與 ~ 跳脫、空白條件,以及 MAXIFS、MINIFS、AVERAGEIFS 與 COUNTUNIQUEIFS。
留言討論
共 0 則留言
