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年第一週



留言
avatar-img
留言分享你的想法!
avatar-img
天空
1會員
20內容數
如果可以無所事事的放空,那才是真的幸福?
天空的其他內容
2025/03/06
使用 ldap3 2.9.1 pip install ldap3​ python: from ldap3 import Server, Connection, SIMPLE, SYNC, ALL import pandas as p d import json # LDAP 伺服器地址
2025/03/06
使用 ldap3 2.9.1 pip install ldap3​ python: from ldap3 import Server, Connection, SIMPLE, SYNC, ALL import pandas as p d import json # LDAP 伺服器地址
2025/03/06
最近看了一本書「29歲開始做,43歲提早退休…」 書中的大意是, 作者由29歲起,每月將收入的50%都存起來投資基金和買保險(養老險), 到了43歲時因職場上的不順遂,毅然決定提前退休。 書中並沒有詳細指出作者是如何「投資基金和買保險」來建立被動收入, 本書的內容比較多的是描述作者的退休生
Thumbnail
2025/03/06
最近看了一本書「29歲開始做,43歲提早退休…」 書中的大意是, 作者由29歲起,每月將收入的50%都存起來投資基金和買保險(養老險), 到了43歲時因職場上的不順遂,毅然決定提前退休。 書中並沒有詳細指出作者是如何「投資基金和買保險」來建立被動收入, 本書的內容比較多的是描述作者的退休生
Thumbnail
2024/12/19
什麼是 Active Directory? Active Directory (AD)是企業經常用來做電腦登入認證的系統服務,透過 AD 伺服器 IT管理員能夠用來儲存 使用者(User)、使用者群組(Group)和電腦(Computer) …等的相關資訊以進行認證與網域存取管理。 如何
Thumbnail
2024/12/19
什麼是 Active Directory? Active Directory (AD)是企業經常用來做電腦登入認證的系統服務,透過 AD 伺服器 IT管理員能夠用來儲存 使用者(User)、使用者群組(Group)和電腦(Computer) …等的相關資訊以進行認證與網域存取管理。 如何
Thumbnail
看更多
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
最近公司發放了2025年行事曆(以下為示意圖非實際行事曆): 看起來很正常的行事曆,但問題就出現在了週別計算。 歸納後某公司的規則如下: a. 1月1日那一週如果屬於今年的日數大於等於4日,則為第一週W1。 b. 1月1日那一週如果屬於今年的日數小於4日,則為去年最後一週W52或W5
Thumbnail
最近公司發放了2025年行事曆(以下為示意圖非實際行事曆): 看起來很正常的行事曆,但問題就出現在了週別計算。 歸納後某公司的規則如下: a. 1月1日那一週如果屬於今年的日數大於等於4日,則為第一週W1。 b. 1月1日那一週如果屬於今年的日數小於4日,則為去年最後一週W52或W5
Thumbnail
  接續上一篇文章,換言之,不會因為放假不能睡晚而影響到心情,就算六日都早起,週一也可以保持平靜的心情上班。而在新的一年裡,無論是以一月一日或農曆春節過後為起始日,先將計畫安排好,心裡也會有個底,知道這一年要完成什麼計畫。對於工作的內容,可以用兩個角度來思考:         第一,如果是
Thumbnail
  接續上一篇文章,換言之,不會因為放假不能睡晚而影響到心情,就算六日都早起,週一也可以保持平靜的心情上班。而在新的一年裡,無論是以一月一日或農曆春節過後為起始日,先將計畫安排好,心裡也會有個底,知道這一年要完成什麼計畫。對於工作的內容,可以用兩個角度來思考:         第一,如果是
Thumbnail
日期中我們常分為假日與工作日,那EXCEL中如何快速的將工作日迅速的取出來呢? 這篇分享兩種做法: 週一到週五工作日 考慮國定假日與補假日 可以下載練習檔跟著做看看唷 練習檔下載 【📝圖文教學】 📌週一到週五工作日 先輸入一個日期 向下填滿 自動填滿選項 選擇以
Thumbnail
日期中我們常分為假日與工作日,那EXCEL中如何快速的將工作日迅速的取出來呢? 這篇分享兩種做法: 週一到週五工作日 考慮國定假日與補假日 可以下載練習檔跟著做看看唷 練習檔下載 【📝圖文教學】 📌週一到週五工作日 先輸入一個日期 向下填滿 自動填滿選項 選擇以
Thumbnail
一年又過去了,不少人開始計畫今年的特休使用方式。但通常不太會有人剛好就是一月一日到職,所以直接用年初來計算一年又感覺怪怪的,可是如果把每位員工分開來計算,對公司來講又不太方便。究竟特休在勞基法上是否有被規範好的算法呢?還是說要怎麼計算才是正確的?
Thumbnail
一年又過去了,不少人開始計畫今年的特休使用方式。但通常不太會有人剛好就是一月一日到職,所以直接用年初來計算一年又感覺怪怪的,可是如果把每位員工分開來計算,對公司來講又不太方便。究竟特休在勞基法上是否有被規範好的算法呢?還是說要怎麼計算才是正確的?
Thumbnail
今日牌卡:邏輯   https://dcalyson0110.pixnet.net/blog/post/129609259   2024年第一周的上班日已度過 有什麼想法?還是感覺如何?   以前身為上班族的我就跟大家一樣 這個月除了例行事務的進行,之前專案的收尾外 其實,大部分工
Thumbnail
今日牌卡:邏輯   https://dcalyson0110.pixnet.net/blog/post/129609259   2024年第一周的上班日已度過 有什麼想法?還是感覺如何?   以前身為上班族的我就跟大家一樣 這個月除了例行事務的進行,之前專案的收尾外 其實,大部分工
Thumbnail
今天,是2024年元旦連假後的開工日。 而明天,明天是在我新年理想藍圖之中,啟動第一個行動計畫的開始。
Thumbnail
今天,是2024年元旦連假後的開工日。 而明天,明天是在我新年理想藍圖之中,啟動第一個行動計畫的開始。
Thumbnail
職場很常見的問題,日期工作日計算並且將週六與週日考慮進去,如下圖的例子,開始日期是6/19,經過5天候會是幾月幾號呢? 如果不包含六日6/19經過5天的話是6/24號,可以直接6/19+5就會得到6/24了,但如果扣除6/22(端午節)、6/23(補假)、6/24(六)、6/25(日)不算的話,經
Thumbnail
職場很常見的問題,日期工作日計算並且將週六與週日考慮進去,如下圖的例子,開始日期是6/19,經過5天候會是幾月幾號呢? 如果不包含六日6/19經過5天的話是6/24號,可以直接6/19+5就會得到6/24了,但如果扣除6/22(端午節)、6/23(補假)、6/24(六)、6/25(日)不算的話,經
Thumbnail
Hi, 大家好。我是茶桁。 上一节课最后,我让我家去预习一下日历和时间的相关模块,不知道大家有没有去预习。不管如何,这节课,让我们开始做一个练习:万年历。 没有预习的小伙伴也跟着一起,在本次练习完成的时候,相信你会对这些模块有了初步的了解。 好,让我们开始吧。 首先,我们需要来看看calen
Thumbnail
Hi, 大家好。我是茶桁。 上一节课最后,我让我家去预习一下日历和时间的相关模块,不知道大家有没有去预习。不管如何,这节课,让我们开始做一个练习:万年历。 没有预习的小伙伴也跟着一起,在本次练习完成的时候,相信你会对这些模块有了初步的了解。 好,让我们开始吧。 首先,我们需要来看看calen
Thumbnail
2023 到了,今年有什麼新規劃嗎?或是有什麼重要的日子值得倒數一下呢?我們可以在試算表用三個方法,計算兩個日期的相差天數,當然計算倒數日也可以。一起來看看吧!
Thumbnail
2023 到了,今年有什麼新規劃嗎?或是有什麼重要的日子值得倒數一下呢?我們可以在試算表用三個方法,計算兩個日期的相差天數,當然計算倒數日也可以。一起來看看吧!
Thumbnail
除了檢查行事曆以外,有沒有什麼方式,可以讓excel直接回傳該日是星期幾呢? 這時,使用的是【WEEKDAY】函數。我們預計在日期下的儲存格,顯示出星期幾,所以點選該位置。
Thumbnail
除了檢查行事曆以外,有沒有什麼方式,可以讓excel直接回傳該日是星期幾呢? 這時,使用的是【WEEKDAY】函數。我們預計在日期下的儲存格,顯示出星期幾,所以點選該位置。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News