我有一個程式,用戶可以在其中設定事件,其中包含開始日期、結束日期和事件重復的周期,每周、每月按日期、每月按作業日和每年重復。用戶創建事件后,它會保存在資料庫中,并且該事件會顯示在我程式主頁上的日歷中。
到目前為止,我已經能夠設計出每周、每月按日期和每年重復日期的演算法,但不能按作業日每月重復。我所說的“按作業日按月計算”是指在開始日期和結束日期所占據的時間段內,每月在每個相同的作業日重復一次的事件。
例如,在 3 月 1 日和 11 月 1 日之間重復每個月的第一個星期一的事件,3 月 1 日是 3 月的第一個星期一,所以我想生成一個日期,即 4 月的第一個星期一,即 4 月 5 日,以此類推,每個月在 3 月和 11 月之間。
下面的代碼片段是我按日期每月重復日期的功能,這是用于在開始日期和結束日期之間每 15 日重復一次的事件。
function repeatEventMonthly(jsonArray, num){
//First I get the start date and end date as strings on a JSON, I separate
//them by the "/" and then use the individual parts to construct two Date Objects
var split = jsonArray[num].Fecha.split("/");
var split2 = jsonArray[num].fechaFin.split("/");
var dd = split[1];
var mm = split[0];
var yy = split[2];
var dd2 = split2[1];
var mm2 = split2[0];
var yy2 = split2[2];
var starDate = new Date();
var endDate = new Date();
starDate.setFullYear(yy);
starDate.setMonth(mm-1);
starDate.setDate(dd);
endDate.setFullYear(yy2);
endDate.setMonth(mm2-1);
endDate.setDate(dd2);
//the variable top means how many days are between the startDate and endDate.
//I use a function that calculates this number
var top = getDaysInDates(starDate, endDate);
if (jsonArray[num].tipoRepeticion == "2") {
//the attribute "tipoRepeticion" in my JSON object lets me know what type of
//repetition the event must be set, 2 means Monthly by Weekday and 3 is Monthly by Date
}else if(jsonArray[num].tipoRepeticion == "3"){
//If the event has repetition type 3, then inside this for loop I generate a new date
//which I create with the value of the startDate and then I add the index number in the for
//loop cycle, meaning that if the startDate is March 3, the in index 1 is March 4, Index 2
//is March 5 and so on, then with an If statement I check that if the date on the
//generated date object is the same as the date of the startDate, I push the date to
//another JSON array that I use to display the dates on the calendar.
for (let index = 0; index < top; index ) {
let sd = new Date(starDate);
sd.setDate(sd.getDate() index);
if (sd.getDate() == starDate.getDate()) {
let str = ((sd.getMonth() 1) "/" sd.getDate() "/" sd.getFullYear()).toString();
eventMen.push({
// the function "construcDates" helps me create a valid String for my program
// to display at the user.
date: constructDates(str, 0, jsonArray[num].tipoRepeticion),
title: jsonArray[num].titulo,
descripcion: jsonArray[num].descripcion,
tipo: jsonArray[num].tipo,
tipoRepeticion : jsonArray[num].tipoRepeticion
});
}
}
}
因此,此功能有效地生成相隔一個月但在同一日期的事件,這意味著如果我的事件從 3 月 3 日開始,到 12 月 3 日結束,則在我的日歷中,它會在 4 月 3 日、5 月 3 日、6 月 3 日、7 月 3 日顯示相同的事件...一直到11月3日。這種方法可能比我需要的更復雜,但我仍在學習 JavaScript,所以這就是我想出的。
然而,盡管已經解決了其他型別重復日期的邏輯,(每周,每月按日期和每年)按作業日每月重復日期變得非常困難,因為每個月的天數不同,例如,我不能僅僅總結每個月的 30 或 31 天,并希望日期落在同一個“一個月的第一個星期一”。我想問一下是否有人對我如何計算這個難題有任何建議或解決方案,還值得指出的是,“任何一個月的第一個星期一”的例子并不是按月重復日期的唯一可能型別,也是可以是每個月的第二個星期二,也可以是最后一個星期五。
uj5u.com熱心網友回復:
要獲得一個月中某一天的第 n 個實體,請為該月的第一天創建一個日期,移動到所需日期的第一個實體,然后添加 (n-1) 周的天數,例如
/* Get nth instance of a particular weekday in a month
*
* @param {number|string} nth - instance of day, 1 to 4
* @param {number|string} day - day of week, Sun 0, Mon 1, etc.
* @param {Date} month - any date in month to get day of
* @returns {Date} that is nth instance of day in month
*/
function getNthDayInMonth(nth, day, month) {
// Create new date for 1st of month
let d = new Date(month.getFullYear(), month.getMonth());
// Move to first instance of day in month and
// add (n - 1) weeks
d.setDate(1 (7 - d.getDay() day)%7 (nth - 1)*7);
return d;
}
// Formater
let f = (d) => new Intl.DateTimeFormat('en-GB', {
weekday:'short',
day:'2-digit',
month:'short',
year: 'numeric'
}).format(d);
// Examples
[[1,1,new Date(2021,11),'1st Mon in Dec 2021'],
[3,3,new Date(2022, 0),'3rd Wed in Jan 2022'],
[4,1,new Date(2022, 1),'4th Mon in Feb 2022'],
[4,2,new Date(2022, 1),'4th Tue in Feb 2022'],
[4,3,new Date(2022, 1),'4th Wed in Feb 2022'],
[1,3,new Date(2022, 5),'1st Wed in Jun 2022'],
[5,5,new Date(2022,11),'5th Fri in Dec 2022']
].forEach(a => {
let [n,d,m,note] = a;
console.log(`${note}: ${f(getNthDayInMonth(n,d,m))}`);
});
一個月中的每一天總是至少有 4 個實體,某些日子最多有 5 個實體(例如,2022 年 1 月有 5 個星期六、星期日和星期一)。第n 個引數可能限制為 4,或者如果允許第 5 個實體,則將其限制為 5,然后檢查結束月份是否與開始月份相同。如果不是,則拋出錯誤或回傳 undefined。
要獲取兩個日期之間的所有第 n 天,請遍歷月份以獲取第 n 個實體并洗掉開始之前或結束之后的所有日期。
uj5u.com熱心網友回復:
你能不能得到一個月第一天的星期幾,然后從中找出距離所需的星期幾的天數。然后加上 7 的乘積,直到得到所需的日期。
例如:
const startDate = new Date("2021-03-01"); // Mon Mar 01 2021
const friday = 5; // Friday is the 5th day of the week (Monday is 1)
const weekOfMonth = 2; // We want the 3rd week of the month (1st week is 0)
// Start calculations
const dayOfWeek = startDate.getUTCDay(); // 1
const diff = friday - dayOfWeek; // 4
const dateOf3rdFriday = new Date(
startDate.getUTCFullYear(),
startDate.getUTCMonth(),
startDate.getUTCDay() diff 7 * weekOfMonth
); // Fri Mar 19 2021
在本月的最后一個星期五,你只需要做同樣的事情,但反過來。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/372298.html
標籤:javascript json 日期
上一篇:VBA中日期格式的區別
