javascript 計算某公司行事曆週別

閱讀時間約 10 分鐘

最近公司發放了2025年行事曆(以下為示意圖非實際行事曆):

raw-image

看起來很正常的行事曆,但問題就出現在了週別計算。

歸納後某公司十年來的行事曆的規則如下:

a. 1月1日那一週如果屬於今年的日數大於等於4日,則為第一週W1。

b. 1月1日那一週如果屬於今年的日數小於4日,則為去年最後一週W52或W53。

c. 每一週以星期一為開始日。

d. ....

以下為 javascript 程式碼:

/// 行事曆 週別計算
function getWeekNumber(dateInput) {
console.log('輸入的日期是:' + dateInput);
const date = new Date(dateInput); // 將輸入的字串轉為日期
const year = date.getFullYear(); // 取得輸入日期的年份
const firstDayOfYear = new Date(year, 0, 1); // 取得該年份1月1日
const dayOfWeek_firstDayOfYear = firstDayOfYear.getDay(); // 取得1月1日是星期幾
// 尋找該年份的第一個星期一
const firstMonday = new Date(firstDayOfYear);
if (dayOfWeek_firstDayOfYear !== 1) {
const daysToAdd = (8 - dayOfWeek_firstDayOfYear) % 7; // 計算距離下個星期一的天數
firstMonday.setDate(firstMonday.getDate() + daysToAdd);
}
// 計算從第一個星期一到指定日期的差距,以天數計算
const differenceInDays = Math.floor((date - firstMonday) / (1000 * 60 * 60 * 24));
// 週數計算
let weekNumber = Math.floor(differenceInDays / 7) + 1; // 週數從1開始
if (dayOfWeek_firstDayOfYear >= 2 && dayOfWeek_firstDayOfYear <= 4) {
weekNumber += 1; // 如果1月1日屬於星期二到星期四,則週數加1
}
// 若週數為0,計算去年的最後一個星期
if (weekNumber === 0) {
const lastYear = year - 1;
const lastDayOfLastYear = new Date(lastYear, 11, 31);
const firstDayOfLastYear = new Date(lastYear, 0, 1);
// 尋找去年第一個星期一
const firstMondayOfLastYear = new Date(firstDayOfLastYear);
if (firstDayOfLastYear.getDay() !== 1) {
// 計算距離下個星期一的天數
const daysToAdd_lastyear = (8 - firstMondayOfLastYear.getDay()) % 7;
firstMondayOfLastYear.setDate(firstMondayOfLastYear.getDate() + daysToAdd_lastyear);
}
const differenceInDays_lastyear = Math.floor((lastDayOfLastYear - firstMondayOfLastYear) / (1000 * 60 * 60 * 24));
weekNumber = Math.floor(differenceInDays_lastyear / 7) + 1; // 加 1 因為週數是從 1 開始
if (firstDayOfLastYear.getDay() >= 2 && firstDayOfLastYear.getDay() <= 4) {
weekNumber += 1; // 同樣的條件,若是週二到週四,週數加1
}
return `${lastYear}-W${weekNumber}`; // 返回結果
}
// 若週數為53,檢查今年的最後一天
else if (weekNumber === 53) {
const lastDayOfYear = new Date(year, 11, 31);
const dayOfWeek_lastDayOfYear = lastDayOfYear.getDay(); // 取得年底的星期幾
if (dayOfWeek_lastDayOfYear > 0 && dayOfWeek_lastDayOfYear < 4) {
return `${year + 1}-W1`; // 如果最後一天屬於週一到週四,則為下一年的第一週
} else {
return `${year}-W${weekNumber}`; // 否則就是今年的53週
}
} else {
return `${year}-W${weekNumber}`; // 返回結果
}
}

function getDateRange(weekInput) {
console.log('輸入的週別是:' + weekInput);
// 解析輸入的週數格式,例如 '2024-W1' 或 '2026-W20'
const [year, week] = weekInput.split('-W').map(Number);
// 計算每週的第一天,即從每年的第一天開始
const firstDayOfYear = new Date(year, 0, 1); // 取得該年份1月1日
const dayOfWeek_firstDay = firstDayOfYear.getDay(); // 取得該年份1月1日是星期幾?
//console.log('該年份第一天是星期幾?'+dayOfWeek_firstDay);
// 計算該年份第一週的啟始日期
const firstWeekOfYearStartDate = new Date(firstDayOfYear)
// 每年第一週需 >= 4天,只有1月1日在星期一~星期四,該年份第一週才會包含1月1日
if(dayOfWeek_firstDay >=1 && dayOfWeek_firstDay <= 4){
firstWeekOfYearStartDate.setDate(firstDayOfYear.getDate() - (dayOfWeek_firstDay-1));
} else if(dayOfWeek_firstDay === 0){
firstWeekOfYearStartDate.setDate(firstDayOfYear.getDate() + 1);
} else {
firstWeekOfYearStartDate.setDate(firstDayOfYear.getDate() + (7-dayOfWeek_firstDay+1));
}
//console.log('該年份第一週的啟始日期:'+firstWeekOfYearStartDate);

// 計算該週的開始日期
const startDate = new Date(firstWeekOfYearStartDate);
startDate.setDate(startDate.getDate() + (week - 1) * 7); // 計算開始日期
// 計算該週的結束日期
const endDate = new Date(startDate);
endDate.setDate(endDate.getDate() + 6); // 結束日期是開始日期的6天後
// 格式化日期為 YYYY-MM-DD 格式
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份從0開始,需加1
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
// 輸出結果範圍
return `${formatDate(startDate)}~${formatDate(endDate)}`;
}

接下來我們驗證一下算法:

raw-image

2016/01/02 一般都會認為是2016年第一週,依但某公司規則,硬生生變成了2015W53

raw-image

2025/12/31 依但某公司規則為2026年第一週



0會員
5內容數
如果可以無所事事的放空,那才是真的幸福?
留言0
查看全部
發表第一個留言支持創作者!
天空 的其他內容
最近公司發送了2025年行事曆,無聊的我突然想起來,之前廠商送的好多萬用手冊都沒有用,不知道那一年的日期排列和明年相同,於是就有了以下的畫面: 程式碼如下: <!DOCTYPE html> <html lang="zh-Hant"> <head> <meta charset="UTF-8"
最近有一個需求是多個寬度相同的Div捲軸要連動的功能,如下圖: 這程式單純使用jquery就可以完成: <!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="UTF-8"> <meta name="viewport" con
使用 GD庫: 1.先確認 PHP GD lib 是否已安裝,利用 phpinfo() 頁面來檢查。 <?php phpinfo(); ?> 如果出現 GD Support "enabled",就是有啟用 GD lib了, 如果沒有的話,請打開 php.ini 找到 ;extension=
最近公司發送了2025年行事曆,無聊的我突然想起來,之前廠商送的好多萬用手冊都沒有用,不知道那一年的日期排列和明年相同,於是就有了以下的畫面: 程式碼如下: <!DOCTYPE html> <html lang="zh-Hant"> <head> <meta charset="UTF-8"
最近有一個需求是多個寬度相同的Div捲軸要連動的功能,如下圖: 這程式單純使用jquery就可以完成: <!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="UTF-8"> <meta name="viewport" con
使用 GD庫: 1.先確認 PHP GD lib 是否已安裝,利用 phpinfo() 頁面來檢查。 <?php phpinfo(); ?> 如果出現 GD Support "enabled",就是有啟用 GD lib了, 如果沒有的話,請打開 php.ini 找到 ;extension=
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
2025年即將到來,對於計劃全年活動和休假的人來說,了解中華民國2025年行事曆至關重要。本文將為您提供詳細的2025年行事曆資訊,包括國定假日、請假攻略,幫助您提前做好安排。
Thumbnail
可能包含敏感內容
選擇你腦海中的數字,本週將會迎來甚麼樣的訊息和自我提醒呢?
Thumbnail
  接續上一篇文章,換言之,不會因為放假不能睡晚而影響到心情,就算六日都早起,週一也可以保持平靜的心情上班。而在新的一年裡,無論是以一月一日或農曆春節過後為起始日,先將計畫安排好,心裡也會有個底,知道這一年要完成什麼計畫。對於工作的內容,可以用兩個角度來思考:         第一,如果是
Thumbnail
製作月曆或是排班表,常常會將週末的儲存格填上不同的顏色,來區分平日與假日。 但如果你還在手動慢慢調整,那你就太落伍囉~~ 這集教你3種常見標示的方法: 週末(六日)日期標示 週末(六日)含國定假日標示 週末(六日)並考慮國定假日與補班標示 📌週末(六日)標示 選取資
Thumbnail
法定正常工作時間自105年1月1日起縮減為每週不得超過四十小時,為落實週休二日,例假日僅限因天災、事變或突發事件等特殊原因始得出勤之嚴格規範,定明勞工每七日應有之二日之休息,其中一日為例假,另一日為休息日。 實施二週及八週彈性工作時間之例假仍維持每七日至少一日,僅休息日可彈性調整,惟例假及休息日之
Thumbnail
今日牌卡:邏輯   https://dcalyson0110.pixnet.net/blog/post/129609259   2024年第一周的上班日已度過 有什麼想法?還是感覺如何?   以前身為上班族的我就跟大家一樣 這個月除了例行事務的進行,之前專案的收尾外 其實,大部分工
Thumbnail
因為我們每天都會被問不只一次,乾脆把日期都整理出來,這樣大家查找更方便。 整年的新月|滿月| 八大節慶的日期都在上面囉。 因為是工作了10個小時後老眼昏花整理出來的,如果有誤植的話,再跟我們說,會立即修正喔。 預祝大家週末愉快。我們也要下班落跑啦~ ▍限量Imbolc蠟燭預購中:
Thumbnail
今天,是2024年元旦連假後的開工日。 而明天,明天是在我新年理想藍圖之中,啟動第一個行動計畫的開始。
Thumbnail
2024年1月2日 面對長假,目前還是只有『平常休假』的感覺。 因為去年底趕著專案結案,沒有時間和進行業務交接,當有時間時,同事已經在休年假了,只好把交接挪到新年度再啟動。(朋友笑我,我在休假就要工作交接,為什麼同事要休假就需要配合?!我也太好說話了吧!大概就是吧!)
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
2025年即將到來,對於計劃全年活動和休假的人來說,了解中華民國2025年行事曆至關重要。本文將為您提供詳細的2025年行事曆資訊,包括國定假日、請假攻略,幫助您提前做好安排。
Thumbnail
可能包含敏感內容
選擇你腦海中的數字,本週將會迎來甚麼樣的訊息和自我提醒呢?
Thumbnail
  接續上一篇文章,換言之,不會因為放假不能睡晚而影響到心情,就算六日都早起,週一也可以保持平靜的心情上班。而在新的一年裡,無論是以一月一日或農曆春節過後為起始日,先將計畫安排好,心裡也會有個底,知道這一年要完成什麼計畫。對於工作的內容,可以用兩個角度來思考:         第一,如果是
Thumbnail
製作月曆或是排班表,常常會將週末的儲存格填上不同的顏色,來區分平日與假日。 但如果你還在手動慢慢調整,那你就太落伍囉~~ 這集教你3種常見標示的方法: 週末(六日)日期標示 週末(六日)含國定假日標示 週末(六日)並考慮國定假日與補班標示 📌週末(六日)標示 選取資
Thumbnail
法定正常工作時間自105年1月1日起縮減為每週不得超過四十小時,為落實週休二日,例假日僅限因天災、事變或突發事件等特殊原因始得出勤之嚴格規範,定明勞工每七日應有之二日之休息,其中一日為例假,另一日為休息日。 實施二週及八週彈性工作時間之例假仍維持每七日至少一日,僅休息日可彈性調整,惟例假及休息日之
Thumbnail
今日牌卡:邏輯   https://dcalyson0110.pixnet.net/blog/post/129609259   2024年第一周的上班日已度過 有什麼想法?還是感覺如何?   以前身為上班族的我就跟大家一樣 這個月除了例行事務的進行,之前專案的收尾外 其實,大部分工
Thumbnail
因為我們每天都會被問不只一次,乾脆把日期都整理出來,這樣大家查找更方便。 整年的新月|滿月| 八大節慶的日期都在上面囉。 因為是工作了10個小時後老眼昏花整理出來的,如果有誤植的話,再跟我們說,會立即修正喔。 預祝大家週末愉快。我們也要下班落跑啦~ ▍限量Imbolc蠟燭預購中:
Thumbnail
今天,是2024年元旦連假後的開工日。 而明天,明天是在我新年理想藍圖之中,啟動第一個行動計畫的開始。
Thumbnail
2024年1月2日 面對長假,目前還是只有『平常休假』的感覺。 因為去年底趕著專案結案,沒有時間和進行業務交接,當有時間時,同事已經在休年假了,只好把交接挪到新年度再啟動。(朋友笑我,我在休假就要工作交接,為什麼同事要休假就需要配合?!我也太好說話了吧!大概就是吧!)