user18553570
user18553570

Reputation: 1

Calculating dates in Python with dependies on hour and name of day

I am developing an application where users can make a reservation for a car and the fee for the reservation depends on which hours and which day of the week the reservation takes places.

The rules for the fee calculation are:

  1. Monday until Friday 7am - 7 pm (during the day): 2.00 Dollars per hour
  2. Monday until Friday 7am - 7 am (during the night): 0.50 Dollars per hour
  3. Saturday and Sunday (every hour during the day and night): 0.50 Dollars per hour

Example reservation:

start: Monday, 2023/02/06 - 07:00 am end: Monday, 2023/02/20 - 07:00 am

Calculation:

10 weekdays (monday-friday during the day) with 12 hours * 2.00 = 240.00 
10 weekdays (monday-friday during the night) with 12 hours * 0.50 = 60.00
4 weekend days with 24 hours per day * 0.50 CHF = 48.00

This results in a total fee of 348.00

I am wondering how I could solve this with a function in python with calculates the start date and end dates with dependies on the 3 rules from above.

I even don't know how to start in order to extract the hours and days from the start date and end date.

Upvotes: 0

Views: 101

Answers (3)

najeem
najeem

Reputation: 1921

To calculate the fee for a given reservation, you can write a Python function that takes the start and end dates of the reservation as inputs, and uses datetime module to extract the hours and days from the dates.

import datetime

def calculate_reservation_fee(start_date, end_date):
    weekdays_day_rate = 2.00  # rate for weekdays during the day
    weekdays_night_rate = 0.50  # rate for weekdays during the night
    weekend_rate = 0.50  # rate for weekends
    
    total_fee = 0.00
    
    # iterate over all hours in the reservation period
    current_date = start_date
    while current_date < end_date:
        hour = current_date.hour
        day_of_week = current_date.weekday()  # 0 is Monday, 6 is Sunday
        
        if day_of_week < 5 and 7 <= hour < 19:  # weekday during the day
            total_fee += weekdays_day_rate
        elif day_of_week < 5:  # weekday during the night
            total_fee += weekdays_night_rate
        else:  # weekend
            total_fee += weekend_rate
        
        # move to the next hour
        current_date += datetime.timedelta(hours=1)
    
    return total_fee

Upvotes: 1

billy bud
billy bud

Reputation: 121

This snippet takes input strings as in your example and when executed prints 348 as the desired price. It uses a list to store all prices so it isn't too hard to modify in future if prices change. When index gets to the end of the weekly prices list index will be set back to zero so you can keep adding up the hours as the weeks roll over.

import datetime

# assuming your input format is strings like this
input_start = "Monday, 2023/02/06 - 07:00 am"
input_end = "Monday, 2023/02/20 - 07:00 am"

# cut out the weekday as it doesn't matter
start = datetime.datetime.strptime(input_start.split(", ")[1], "%Y/%m/%d - %I:%M %p")
end = datetime.datetime.strptime(input_end.split(", ")[1], "%Y/%m/%d - %I:%M %p")

# now make a list hourly_prices_week of all the prices of each hour in the week
# the list should be 168 in length (168 hours in a week)

# to build it faster fill in the weekday and weekend first
hourly_prices_weekday = [0.5] * 7 + [2] * 12 + [0.5] * 5
hourly_prices_weekend = [0.5] * 24

# add the 5 weekdays and then 2 weekend days
# note the prices start at the begining of monday
hourly_prices_week = hourly_prices_weekday * 5 + hourly_prices_weekend * 2

print(hourly_prices_week)  # [ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 2, 2, 2, ....]
print(len(hourly_prices_week))  # 168

# find out how many hours are between start and end times
hours = (end - start).total_seconds() / 3600
print(hours)  # 336

# determine what index of hourly_prices your start time is in
index = 0  # this is start of monday
index += start.weekday() * 24  # go forward however many days (monday is 0)
index += start.hour  # go forward however many hours (hour is 0-23)
print(index)  # 7

price = 0
while hours > 0:
    price += hourly_prices_week[index]
    index += 1
    if index >= len(hourly_prices_week):
        index = 0
    hours -= 1

print(price)  # 348

Upvotes: 0

oskros
oskros

Reputation: 3285

I made an example with a custom class built on top of the datetime module, that overrides the subtract method __sub__.

The cost method defines what the price should be in each hour interval using your rules above.

The function date_range from pandas is used to generate each hour between the two dates, which I then apply the cost function on to get the total price

import datetime as dt
from pandas import date_range


class Rental(dt.datetime):
    def __sub__(self, other):
        times = date_range(self, other, freq='H', inclusive='left')
        return sum(self.cost(d) for d in times)

    @staticmethod
    def cost(time):
        if time.weekday() > 4:
            return 0.5
        if 7 <= time.hour < 19:
            return 2
        return 0.5
print(Rental(year=2022, month=3, day=20, hour=0) - Rental(year=2022, month=4, day=3, hour=0))
>>> 348.0

Upvotes: 0

Related Questions