我嘗試使陣列物件包含一個特定月份的第一個和最后一個日期。例如:
{
W1: [ '2021-01-01', '2021-01-07' ],
W2: [ '2021-01-08', '2021-01-14' ],
W3: [ '2021-01-15', '2021-01-21' ],
W4: [ '2021-01-22', '2021-01-28' ],
W5: [ '2021-01-29', '2021-01-31' ]
}
這段代碼還有更多功能性的方法嗎?
// const moment = require('moment'); // require
const getMaxDate = (year, month) => moment(`${year}-${month}`, "YYYY-MM").daysInMonth();
const getDate = (x, y, z) => moment().year(x).month(y).date(z).format("YYYY-MM-DD");
const dateOnMonth = (month, year) => {
const max = getMaxDate(year, month)
let obj = {}
let counter = 0
let last = 0
for (let i = 0; i <= max; i ) {
if (i != 0 && i % 7 == 0) {
counter
const y = getDate(year, month - 1, i - 6)
const z = getDate(year, month - 1, i)
obj[`W${counter}`] = [y, z]
last = i 1
} else if (counter == 4) {
const j = getDate(year, month - 1, last)
const k = getDate(year, month - 1, max)
obj[`W${counter 1}`] = [j, k]
}
}
return obj
}
console.log(dateOnMonth(1, 2021))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>
uj5u.com熱心網友回復:
試試這個,
您在 for 回圈中浪費了太多迭代,而我的代碼在 for 回圈中最多需要 5 次迭代。
根據需要更改月份和年份。
var month = 4; // means May, this index starts from 0 as January
var year = 1986
function get_dates_by_week_of_a_month_year(month,year){
var d = new Date(year, month 1,0);
var num_days = d.getDate();
obj={};
week=1;
for(i=0;i<num_days;i =7){
start = i 1;
end = (i 7) > num_days ? num_days : (i 7);
d1 = new Date(year, month, start).toLocaleDateString('en-CA');
d2 = new Date(year, month, end).toLocaleDateString('en-CA');
obj['W' week ] = [d1,d2];
}
return obj;
}
console.log(get_dates_by_week_of_a_month_year(month,year));
uj5u.com熱心網友回復:
將函式用于將多次使用的代碼是有意義的,但對于瑣碎的函式則沒有意義。我不會為此使用庫,因為演算法非常簡單,而且普通的 JS 幾乎具備所需的一切。
您還可以稍微簡化演算法,例如
/* Return weeks of month
* First week starts on 1st of month and goes for 7 days
* Last week has less than 7 days in any month of more than 28 days
*
* @param {string|number} year - calendar year, e.g. 2020
* @param {string|number} month - calendar month, 1 == Jan, etc.
* @returns {Object} weeks as {weekNumber:[startDate, endDate]}
* where dates are in YYYY-MM-DD format
*/
function getMonthWeeks(year, month) {
// Create a date from the supplied values
let date = new Date(year, month - 1);
// Other variables
let weeks = {};
let week = 0;
// Loop over weeks until exceed month end
while (date.getMonth() < month) {
// Get week number string
let weekNum = `W${ week}`;
// Initialise week array with start date
weeks[weekNum] = [toYMD(date)];
// Increment to end of week
date.setDate(date.getDate() 6);
// If gone past end of month, go back to last day
if (date.getMonth() == month) {
date.setDate(0);
}
// Add last day to week array
weeks[weekNum].push(toYMD(date));
// Increment to start of next week
date.setDate(date.getDate() 1);
}
return weeks;
}
// Helper to format dates
function toYMD(date) {
return date.toLocaleDateString('en-CA');
}
// April 2022
console.log(getMonthWeeks(2022,4));
// May 2022
console.log(getMonthWeeks(2022,5));
給定簡單的演算法,您知道前 4 周將是什么所以真的只需要在前 4 周中插入年份和月份并計算第 5 周的結束(如果有的話)。
您可能會使用庫來添加日期和格式化日期,但我真的不認為有必要。使用:
date.getMonth() == month
檢查月份是否溢位可能有點晦澀,但可以重寫,這樣邏輯就更清晰了,只需要多出一行。
函式不應在不必要地低效的地方使用,例如
const getMaxDate = (year, month) => moment(`${year}-${month}`, "YYYY-MM").daysInMonth();
創建一個字串,將其決議為一個日期,然后呼叫另一個函式來獲取該月中恰好與該月最后一天的日期重合的天數。相比于:
const getMaxDate = (year, month) => moment([year, month-1]).endOf('month').getDate();
和
const getMaxDate = (year, month) => new Date(year, month, 0).getDate();
所有假設月份是日歷月數。
還:
const getDate = (x, y, z) => moment().year(x).month(y).date(z).format("YYYY-MM-DD");
效率非常低(并且因為y是月份而有點令人困惑),請考慮:
const getDate = (year, month, day) => moment([year, month-1, day]).format("YYYY-MM-DD");
最后,鑒于前 4 周每個月的日期完全相同,您可以對日期使用簡單的算術和字串格式,只使用一個日期來計算最后一天,例如
// month is calendar month
function getWeeksInMonth(year, month) {
let z = n => ('0' n).slice(-2);
let endDay = new Date(year, month, 0).getDate();
let weeks = {};
let week = 0;
let day = 1;
// Do first 4 weeks
while (day < endDay) {
weeks['W' week] = [`${year}-${z(month)}-${z(day)}`,
`${year}-${z(month)}-${z(day 6)}`];
day = 7;
}
// Add 5th week if there is one
if (endDay > 28) {
weeks['W5'] = [`${year}-${z(month)}-29`,
`${year}-${z(month)}-${endDay}`];
}
return weeks
}
console.log(getWeeksInMonth(2022,2)); // February
console.log(getWeeksInMonth(2022,4)); // April
我認為這比大量不必要的日期操作和格式化要有效得多。:-)
uj5u.com熱心網友回復:
功能性的,不可變的,可重用的
這是一種功能方法,其中date模塊可以創建日期、訪問構造日期的屬性并以不可變的方式操作日期。weeks是使用簡單日期操作構建的更復雜的操作 -
// date.js
const date = (y, m, d) => new Date(y, m - 1, d)
const day = (t) => t.getDate()
const month = (t) => t.getMonth() 1
const year = (t) => t.getFullYear()
const addDays = (t, n) => date(year(t), month(t), day(t) n)
const daysInMonth = (t) => day(date(year(t), month(t) 1, 0))
const weeks = (t, days = daysInMonth(t)) =>
days <= 7
? [[t, addDays(t, days - 1)]]
: [[t, addDays(t, 6)], ...weeks(addDays(t, 7), days - 7)]
console.log(weeks(date(2022, 1, 1)))
[
[ "2022-01-01T00:00:00.000Z", "2022-01-07T00:00:00.000Z" ],
[ "2022-01-08T00:00:00.000Z", "2022-01-14T00:00:00.000Z" ],
[ "2022-01-15T00:00:00.000Z", "2022-01-21T00:00:00.000Z" ],
[ "2022-01-22T00:00:00.000Z", "2022-01-28T00:00:00.000Z" ],
[ "2022-01-29T00:00:00.000Z", "2022-01-31T00:00:00.000Z" ]
]
如果要將輸出格式化為字串,則應該是對基礎資料型別進行操作的自己的日期操作。在這里您可以看到添加前導零或針對特定語言環境很容易 -
// date.js (continued)
const toString = (t) => `${year(t)}-${month(t)}-${day(t)}`
console.log(weeks(date(2022, 3, 1)).map(w => [toString(w[0]), toString(w[1])]))
[
[ "2022-3-1", "2022-3-7" ],
[ "2022-3-8", "2022-3-14" ],
[ "2022-3-15", "2022-3-21" ],
[ "2022-3-22", "2022-3-28" ],
[ "2022-3-29", "2022-3-31" ]
]
模塊化思考
使您的思維適應基于模塊化的方法很重要。這是新的 JavaScript 前進方式,import允許部分匯入模塊并使編譯器能夠洗掉大量未使用的“死”代碼;一個稱為搖樹的程序。
與類類似,模塊允許其作者有效地黑盒資料,并通過公開匯出的模塊方法提供與資料互動的認可方式。然而,與模塊不同的是,類不能與其實體方法分離。如果您匯入該類以將其用于一種方法,則所有其他方法都將隨之而來。
的底層表示date不一定是Date. 可以使用陣列[year, month, date]、物件{year, month, date}或任何其他表示。模塊的用戶不應該對底層資料型別做出任何假設,而只能使用提供的模塊方法。只要公共方法仍然正常運行,這允許模塊作者自由地進行底層更改和優化。
// date.js
// date : (int, int, int) -> t
const date = (y, m, d) => new Date(y, m - 1, d)
// day : t -> int
const day = (t) => t.getDate()
// month : t -> int
const month = (t) => t.getMonth() 1
// year : t -> int
const year = (t) => t.getFullYear()
// addDays : (t, int) -> t
const addDays = (t, n) => date(year(t), month(t), day(t) n)
// daysInMonth : t -> int
const daysInMonth = (t) => day(date(year(t), month(t) 1, 0))
// weeks : t -> array (t, t)
const weeks = (t, days = daysInMonth(t)) =>
days <= 7
? [[t, addDays(t, days - 1)]]
: [[t, addDays(t, 6)], ...weeks(addDays(t, 7), days - 7)]
// toString : t -> string
const format = (t) => `${year(t)}-${month(t)}-${day(t)}`
export { date, day, month, year, addDays, daysInMonth, weeks, toString }
// main.js
import { date, weeks } from "./date.js"
const feb22 = date(2022, 2, 1)
console.log(weeks(feb22))
// ...
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/461651.html
標籤:javascript 数组 日期 函数式编程
