I am finding my program to be lacking efficiency. Is there a more concise method for solving this issue?

Starting off with my journey in Javascript, I am eager to tackle problems and enhance my skills. One challenge that came my way is the following question. Despite my efforts to solve it step by step, I feel like there might be room for improvement in my code. Is there anyone out there who can assist me in refining it?

QUERY:

I am seeking a JavaScript function that takes two arguments - the date and time of parking (timestamp) and returns the date and time of returning (timestamp). The scenario involves car parking at an airport, which follows certain pricing rules as outlined below.

Parking charges;

  • €2 for the first 20 minutes,

  • increasing to €4 for up to 40 minutes,

  • increasing further to €6 for one hour,

  • updating to €7 for two hours,

  • and then escalating to €9 for three hours,

  • which goes up to €11 for four hours,

  • further rises to €13 for 4-8 hours,

  • and finally hits €15 for 8-24 hours.

  • A flat rate of €16 applies for the initial 24 hours, with each additional day incurring a charge of €9.

This is the current code I have attempted:

    function msToHours(milisecond) {
        let time = milisecond;

        let hour = (time / 60000) / 60;

        return hour;
    }


    //Mins to Hours Function
    function minToHours(miniute){

        let time = miniute;

        let hr = (miniute /60);

        return hr;

    }


    //Finding the nth day Function

    function add24HR(hour, cb) {

        let arr = new Array();

        for (let i = 0; i < hour; i++) {
            if (i % 24 == 0) {
                arr.push(i)
            }
        }
    
        return  `Your Parking Fee is £${(arr.length*cb-cb) + 16}.(${arr.length} days)`
    }

    //Main Function

    const parkingFees = (parkingDate, returnDate) => {

        //Defining dates
        var park = new Date(parkingDate)
        var returned = new Date(returnDate);

        //Variables
        var penaltyFee = 9;
        let totalPrice;


        //Time between park and return (miliseconds)
        let totalTime = returned - park

        //MiliSeconds to Hour
        let totalPark = msToHours(totalTime);

        //Mins to Hours
        if (totalPark <= minToHours(20)) {
            return `Your parking fee is only £${2}.`
        } 

        else if(totalPark > minToHours(20) && totalPark <= minToHours(40)){
            return `Your parking fee is only £${4}.`
        }

        else if(totalPark > minToHours(40) && totalPark <= minToHours(60)){
            return `Your parking fee is only £${6}.`
        }
        else if(totalPark > minToHours(60) && totalPark <= minToHours(120)){
            return `Your parking fee is only £${7}.`
        }
        else if(totalPark > minToHours(120) && totalPark <= minToHours(180)){
            return `Your parking fee is only £${9}.`
        }
        else if(totalPark > minToHours(180) && totalPark <= minToHours(240)){
            return `Your parking fee is only £${11}.`
        }
        else if(totalPark > minToHours(240) && totalPark <= minToHours(480)){
            return `Your fparking fee is only £${13}.`
        }
      
        else if(totalPark > minToHours(480) && totalPark < minToHours(1440)){
            
            return `Your parking fee is only £${15}.`
        }

        else if(totalPark > minToHours(1440) && totalPark < minToHours(2880)){
            
            return `Your parking fee is only £${16}.`
        }

        //if totalPark > 24 HRS

        else {

            totalPrice = add24HR(totalPark, penaltyFee)

        }

        return totalPrice;

    }

    document.querySelector("body").innerHTML = (parkingFees("5/12/2020 18:30", "5/18/2020 18:30"))

Answer №1

If you want to make it more flexible, consider refactoring your code to utilize an Array. By doing so, updating fees becomes a breeze as you can simply edit the prices within that Array:

const steps = [
  { limit:       20, fee:  2 }, // Time limits are in minutes
  { limit:       40, fee:  4 },
  { limit:       60, fee:  6 },
  { limit:   2 * 60, fee:  7 },
  { limit:   3 * 60, fee:  9 },
  { limit:   4 * 60, fee: 11 },
  { limit:   8 * 60, fee: 13 },
  { limit:  24 * 60, fee: 15 }, // You can even use a function for complex rules:
  { limit: Infinity, fee: minutes => 9 * Math.ceil(minutes / 24 / 60) + 7 }
];

// Convert a date string into minutes since 1970-01-01
const dateToMinutes = str => Math.floor(new Date(str).getTime() / 60000);

const calcFee = (parkingDate, returnDate) => {
  const minutesParked = dateToMinutes(returnDate) - dateToMinutes(parkingDate);
  for (let step of steps) {
    if (minutesParked <= step.limit) {
      return isNaN(step.fee) ? step.fee(minutesParked) : step.fee;
    }
  }
};

// Just for testing purposes
const test = (x, y) => (document.body.innerHTML += `<p>${x} - ${y}<br><b>${formatDuration(x, y)}: €${calcFee(x, y)}</b></p>`); const formatDuration = (x, y) => { const d = dateToMinutes(y) - dateToMinutes(x); const res = {d: Math.floor(d / 24 / 60), h: Math.floor((d % (24 * 60)) / 60), m: d % 60}; return `${res.d} days ${res.h} hours ${res.m} min`; };

test("2020-05-12 18:30:00", "2020-05-12 18:40:00");
test("2020-05-12 18:30:00", "2020-05-12 19:00:00");
test("2020-05-12 18:30:00", "2020-05-12 19:30:00");
test("2020-05-12 18:30:00", "2020-05-13 18:29:00");
test("2020-05-12 18:30:00", "2020-05-13 18:31:00");
test("2020-05-12 18:30:00", "2020-05-18 18:30:00");

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process of importing the csv-writer module?

Can we use the import statement instead of const createCSVWriter = require('csv-writer').createObjectCsvWriter; Is there a way to achieve this using import ...

Retrieving user input in Angular and showcasing extracted keywords

I want to give users the flexibility to customize the format of an address according to their preference. To achieve this, there will be a text input where users can enter both keywords and regular text. The goal is to detect when a keyword is entere ...

What is the best way to set an object's value to null in AngularJS?

Check out this code snippet var data={}; data={stdId:"101"}; data={empId:"102"}; data={deptId:"201"}; In my project, I'm receiving data from services into a data object with differing key names such as stdId or empId, etc. I need to set empty val ...

Trouble encountered in PHP: Generating a file from POST data and initiating download prompt for the user not functioning as intended

On my webpage, users fill out forms and input fields, which are then sent to a PHP page via Ajax and $_POST. The PHP file successfully writes the output to a txt file. However, I'm facing an issue trying to prompt the user to download the file on the ...

What is the significance of the underscore prefix in package.json properties?

Can you explain the significance of prefixing properties with an underscore in package.json? What is the reason behind using underscores in this context? "_from": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6b190e0a081 ...

Click a button to switch the visibility of a section in an

Is there a way to create a toggle feature in Angular.JS that will open and close a div when clicked on the same div again? Currently, it opens the div when clicked but I want it to also close the div when clicked again. <a ng-href ng-click="openAccordi ...

Attempting to configure a webhook eventsub through the Twitch API by utilizing ngrok as the intermediary

After triggering a test event using the Twitch CLI, an error response was received indicating: Post "https://1562-5-182-32-19.ngrok.io/api/twitch/eventsub/": context deadline exceeded (Client.Timeout exceeded while awaiting headers). The notification even ...

Error with decodeURIComponent function in Internet Explorer 8

My widget, loaded as an iframe, requires data about the hosting page. I have UTF-8 strings extracted from a page with Russian text. The page itself has proper HTML5 doctype and meta charset. This is how my code operates: params = "x1=" + encodeURICompone ...

Efficient initialization process in Vue.js components

Upon initialization of a component, the data callback is executed as follows: data(){ return { name: myNameGetter(), age: myAgeGetter(), // etc... } }, Following that, a notification is sent to a parent component regarding ...

What is the best way to selectively print the contents of a child window upon page load?

I've created a function that opens a child window and fills it with content using AJAX. function OpenWindow(){ jQuery.ajax({ type: 'POST', data: { //some fields }, url: 'getPageForPrint.php', su ...

Creating a grid UI in AngularJS using Typescript: utilizing functions as column values

I am working on an AngularJS app that includes the following UI grid: this.resultGrid = { enableRowSelection: true, enableRowHeaderSelection: false, enableHorizontalScrollbar: 0, enableSorting: true, columnDefs: [ { name: &apos ...

Creating a task list without using JavaScript in the web browser and without relying on a database

Looking for some guidance on building a todo app for a job interview where JavaScript is disabled in the browser and no database can be used. Any JavaScript needs to be handled on the server side. I have some basic knowledge of node/express and serving H ...

using ng-show to display array elements

There is a syntax error showing up on the console for the code below, but it still functions as intended. Can someone help identify what I might be missing? <p class="light" data-ng-show="selectedAppType in ['A1','A2','A3' ...

Using jQuery to target the element before

Is there a way to determine the width of elements located before an element when it is hovered over? I attempted to achieve this using the following code: $('ul li').hover(function() { $(this).prevAll().each(function() { var margin = $(this ...

Updating your Heroku app (Node.js) from a GitHub repository - a step-by-step guide

I attempted to deploy my React app using the following process: git status git remote add origin <repo link> git commit -m "node js" git add . Unfortunately, this method did not work for me. Can anyone provide guidance on how to update a ...

Developing an easily optimized library using rollup to remove unnecessary code branches

I'm currently in the process of developing a component library using rollup and Vue with the goal of making it tree shakable for others who import it. The configuration setup is outlined below: Here's a snippet from package.json { "name": "re ...

Unable to dispatch actions within the mounted lifecycle hook in Vuex?

Can anyone explain why the json data I fetch with axios is not populating my state.pages as expected? Interestingly, when I make a change to the file and vite reloads, the data appears on the page. However, it disappears again upon refreshing the browser. ...

What is the process of querying both a collection and a subcollection in Firebase using AngularFire?

I have a structure in my firebase database that looks like this: /profiles/{uid}/displayName /email /otherAttribues /roles/{roleName}/someAttribute /someOtherAttribute The reason ...

"Unlocking the Potential of Babylon.js and Three.js for Exporting Pur

Currently, I am trying to convert a babylon.js model in .babylon format to either .obj or .stl (or any other format compatible with Maya). After searching for a solution within babylon.js itself, I found that three.js has a "save as obj" function in its ed ...

Adjusting the color of specific sections within a text box

Can I change the color of a specific section of a text input box? I'm working on a comment widget that needs everything between the @ and : symbols to be in a different color: <input type="text" placeholder="Want To Say Something?" value="@user55 ...