我们想通过JavaScript根据几个月来计算季节性价格。
预期返回的数据将包含以下详细信息。
Total Days;
Total Cost;
Days from Jan;
Days from Feb;
Days from Mar;
Days from Apr;
Days from May;
Days from June;
...从七月开始,从八月开始,从九月开始,可能会继续这样的日子。
trincot的回答非常好,但没有安排好。是否可以按照预期的数组扩展代码?
提前谢谢你。
// Utility function to facilitate day counting without timezone issues:
const dayNumber = a => Date.UTC(a.getFullYear(), a.getMonth(), a.getDate()) / (24*60*60*1000);
function getPrices(allSeasons, arrival, departure) {
return allSeasons.reduce( (totalPrice, {startDate, endDate, costRate}) => {
let daysInSeason = Math.min(dayNumber(endDate) + 1, dayNumber(departure))
- Math.max(dayNumber(startDate), dayNumber(arrival));
return totalPrice + (daysInSeason > 0 && daysInSeason * costRate);
}, 0);
}
const allSeasons = [
{startDate: new Date(2022, 1-1, 1), endDate: new Date(2022, 1, 0), costRate: 6500},
{startDate: new Date(2022, 2-1, 1), endDate: new Date(2022, 2, 0), costRate: 6500},
{startDate: new Date(2022, 3-1, 1), endDate: new Date(2022, 3, 0), costRate: 6500},
{startDate: new Date(2022, 4-1, 1), endDate: new Date(2022, 4, 0), costRate: 6500},
{startDate: new Date(2022, 5-1, 1), endDate: new Date(2022, 5, 0), costRate: 6500},
{startDate: new Date(2022, 6-1, 1), endDate: new Date(2022, 6, 0), costRate: 8000},
{startDate: new Date(2022, 7-1, 1), endDate: new Date(2022, 7, 0), costRate: 9000},
{startDate: new Date(2022, 8-1, 1), endDate: new Date(2022, 8, 0), costRate: 9000},
{startDate: new Date(2022, 9-1, 1), endDate: new Date(2022, 9, 0), costRate: 8000},
{startDate: new Date(2022, 10-1, 1), endDate: new Date(2022, 10, 0), costRate: 6500},
{startDate: new Date(2022, 11-1, 1), endDate: new Date(2022, 11, 0), costRate: 6500},
{startDate: new Date(2022, 12-1, 1), endDate: new Date(2022, 12, 0), costRate: 6500},
{startDate: new Date(2023, 1-1, 1), endDate: new Date(2023, 1, 0), costRate: 6500},
{startDate: new Date(2023, 2-1, 1), endDate: new Date(2023, 2, 0), costRate: 6500},
{startDate: new Date(2023, 3-1, 1), endDate: new Date(2023, 3, 0), costRate: 6500},
{startDate: new Date(2023, 4-1, 1), endDate: new Date(2023, 4, 0), costRate: 6500},
{startDate: new Date(2023, 5-1, 1), endDate: new Date(2023, 5, 0), costRate: 6500},
{startDate: new Date(2023, 6-1, 1), endDate: new Date(2023, 6, 0), costRate: 8000},
{startDate: new Date(2023, 7-1, 1), endDate: new Date(2023, 7, 0), costRate: 9000},
{startDate: new Date(2023, 8-1, 1), endDate: new Date(2023, 8, 0), costRate: 9000},
{startDate: new Date(2023, 9-1, 1), endDate: new Date(2023, 9, 0), costRate: 8000},
{startDate: new Date(2023, 10-1, 1), endDate: new Date(2023, 10, 0), costRate: 6500},
{startDate: new Date(2023, 11-1, 1), endDate: new Date(2023, 11, 0), costRate: 6500},
{startDate: new Date(2023, 12-1, 1), endDate: new Date(2023, 12, 0), costRate: 6500},
],
embarkation0 = new Date(2022, 6-1, 18),
disembarkation0 = new Date(2022, 6-1, 25),
totalPrice0 = getPrices(allSeasons, embarkation0, disembarkation0);
console.log('7x8.000 (18,19,20,21,22,23,24) Should be 56.000 = ' + totalPrice0);
embarkation1 = new Date(2022, 6-1, 25),
disembarkation1 = new Date(2022, 7-1, 02),
totalPrice1 = getPrices(allSeasons, embarkation1, disembarkation1);
console.log('6x8.000 (25,26,27,28,29,30) + 1x9.000 (01) Should be 57.000 instead of ' + totalPrice1);
embarkation2 = new Date(2022, 8-1, 20),
disembarkation2 = new Date(2022, 8-1, 27),
totalPrice2 = getPrices(allSeasons, embarkation2, disembarkation2);
console.log('7x9.000 (20,21,22,23,24,25,26) Should be 63.000 = ' + totalPrice2);
embarkation3 = new Date(2022, 8-1, 27),
disembarkation3 = new Date(2022, 9-1, 03),
totalPrice3 = getPrices(allSeasons, embarkation3, disembarkation3);
console.log('5x9.000 (27,28,29,30,31) + 2x8.000 (01,02) Should be 61.000 instead of ' + totalPrice3);
embarkation4 = new Date(2022, 9-1, 24),
disembarkation4 = new Date(2022, 10-1, 01),
totalPrice4 = getPrices(allSeasons, embarkation4, disembarkation4);
console.log('7x8.000 (24,25,26,27,28,29,30) Should be 56.000 instead of ' + totalPrice4);
embarkation5 = new Date(2023, 8-1, 26),
disembarkation5 = new Date(2023, 9-1, 02),
totalPrice5 = getPrices(allSeasons, embarkation5, disembarkation5);
console.log('6x9.000 (26,27,28,29,30,31) + 1x8.000 (01) Should be 62.000 instead of ' + totalPrice5);
embarkation6 = new Date(2024, 8-1, 28),
disembarkation6 = new Date(2024, 9-1, 05),
totalPrice6 = getPrices(allSeasons, embarkation6, disembarkation6);
console.log('Non Exist Value 3x9.000 (28,29,30) + 4x8.000 (01,02,03,04) Should be 59.000 instead of ' + totalPrice6);
发布于 2022-11-17 21:01:36
由于您的季节与日历月相对应,我建议使用一种更简单的数据结构:每年一个数组,每个数组有12个价格,该年每个月一个。
守则可如下:
// Utility functions
const dateParts = a => [a.getFullYear(), a.getMonth(), a.getDate()];
const daysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
function getPrices(allSeasons, arrival, departure) {
let [year, month, day] = dateParts(arrival);
let [year2, month2, day2] = dateParts(departure);
let totalPrice = 0, totalDays = 0;
const monthDays = Array(12).fill(0);
for (let diff = year2*12 + month2 - (year*12 + month); diff >= 0; diff--) {
const price = (allSeasons[year] ?? Object.values(allSeasons).at(-1))[month];
const days = (diff ? daysInMonth(year, month) + 1 : day2) - day;
totalPrice += price * days;
totalDays += days;
monthDays[month] += days;
day = 1;
month = (month + 1) % 12;
year += !month;
}
return [totalDays, totalPrice, ...monthDays];
}
const allSeasons = {
2022: [6500, 6500, 6500, 6500, 6500, 8000, 9000, 9000, 8000, 6500, 6500, 6500],
2023: [6500, 6500, 6500, 6500, 6500, 8000, 9000, 9000, 8000, 6500, 6500, 6500],
};
function test(embarkation, disembarkation, expected, msg) {
let details = getPrices(allSeasons, embarkation, disembarkation);
console.log(...details);
if (details[1] !== expected) {
console.log(msg, "Expected", expected, "but got", totalPrice);
}
}
test(new Date(2022, 6-1, 18), new Date(2022, 6-1, 25), 56000, '7x8.000 (18,19,20,21,22,23,24)');
test(new Date(2022, 6-1, 25), new Date(2022, 7-1, 2), 57000, '6x8.000 (25,26,27,28,29,30) + 1x9.000 (01)');
test(new Date(2022, 8-1, 20), new Date(2022, 8-1, 27), 63000, '7x9.000 (20,21,22,23,24,25,26)');
test(new Date(2022, 8-1, 27), new Date(2022, 9-1, 3), 61000, '5x9.000 (27,28,29,30,31) + 2x8.000 (01,02)');
test(new Date(2022, 9-1, 24), new Date(2022, 10-1, 1), 56000, '7x8.000 (24,25,26,27,28,29,30)');
test(new Date(2023, 8-1, 26), new Date(2023, 9-1, 2), 62000, '6x9.000 (26,27,28,29,30,31) + 1x8.000 (01)');
test(new Date(2024, 8-1, 28), new Date(2024, 9-1, 5), 68000, 'Non Exist Value 4x9.000 (28,29,30,31) + 4x8.000 (01,02,03,04)');
console.log("tests completed");
https://stackoverflow.com/questions/74475345
复制相似问题