首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >根据JavaScript中的季节(日期)计算价格

根据JavaScript中的季节(日期)计算价格
EN

Stack Overflow用户
提问于 2022-11-17 12:18:13
回答 1查看 71关注 0票数 -1

我们想通过JavaScript根据几个月来计算季节性价格。

预期返回的数据将包含以下详细信息。

代码语言:javascript
运行
复制
Total Days;
Total Cost;
Days from Jan;
Days from Feb;
Days from Mar;
Days from Apr;
Days from May;
Days from June;
...

从七月开始,从八月开始,从九月开始,可能会继续这样的日子。

trincot的回答非常好,但没有安排好。是否可以按照预期的数组扩展代码?

提前谢谢你。

代码语言:javascript
运行
复制
    // 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);

EN

回答 1

Stack Overflow用户

发布于 2022-11-17 21:01:36

由于您的季节与日历月相对应,我建议使用一种更简单的数据结构:每年一个数组,每个数组有12个价格,该年每个月一个。

守则可如下:

代码语言:javascript
运行
复制
// 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");

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74475345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档