I can help you with that. Here's a step-by-step solution to the problem.

Creating a Deadline Based on Criteria

Introduction

In this article, we’ll explore how to create a deadline based on specific criteria using Python and the pandas library. We’ll cover how to calculate deadlines for dates that fall on weekends or holidays, as well as for dates within specific time ranges.

Holidays and Weekends

When dealing with deadlines that are relative to specific dates, we need to consider holidays and weekends. A holiday is a day when most businesses are closed, while a weekend is a period of two consecutive days when most businesses are closed.

In this example, we’ll assume that the following dates are holidays:

Date
2018-01-01
2018-01-15
2018-02-19
2018-03-09

We can represent these holidays as a list of pandas datetime objects.

Holidays = [date(2018,1,1), date(2018,1,15), date(2018,2,19), date(2018,3,9)]

Calculating Deadlines

To calculate deadlines based on specific criteria, we’ll use a combination of pandas’ built-in functions and custom logic.

Criteria 1: Holiday or Weekend

If the date falls on a holiday or weekend, we need to set the deadline to the next business day at 17:00 hours.

import pandas as pd

# Define holidays and weekends
Holidays = [date(2018,1,1), date(2018,1,15), date(2018,2,19), date(2018,3,9)]
weekend_days = [5, 6]  # Saturday and Sunday are represented by 5 and 6

# Define a function to check if a day is a holiday or weekend
def is_holiday_or_weekend(date):
    return date in Holidays or date.weekday() in weekend_days

# Define a list of dates with their corresponding deadlines
df = pd.DataFrame({
    'Date': ['2018-01-01 18:47', '2018-01-08 06:11', '2018-01-12 10:05', '2018-02-10 09:22', 
             '2018-02-20 14:14', '2018-03-08 16:17', '2018-03-25 17:35'],
    'Deadline': ['2018-01-03 17:00', '2018-01-09 17:00', '2018-01-17 10:05', '2018-02-13 17:00', 
                '2018-02-23 14:14', '2018-03-13 16:17', '2018-03-27 17:00']
})

# Convert dates to pandas datetime objects
df['Date'] = pd.to_datetime(df['Date'])

# Calculate deadlines based on holidays and weekends
def calculate_deadlines(df):
    df['Deadline'] = ''
    
    for index, row in df.iterrows():
        date = row['Date']
        
        # Check if the date is a holiday or weekend
        if is_holiday_or_weekend(date):
            next_business_day = date + pd.Timedelta(days=1)
            while not (next_business_day.weekday() < 5 and next_business_day.hour == 17):
                next_business_day += pd.Timedelta(days=1)
            
            df.at[index, 'Deadline'] = next_business_day.strftime('%Y-%m-%d %H:%M')
        else:
            # Calculate the deadline for dates within specific time ranges
            if (date.weekday() < 5 and date.hour >= 0 and date.hour <= 8):
                next_non_holiday_day = date + pd.Timedelta(days=1)
                while not ((next_non_holiday_day.weekday() < 5) and (next_non_holiday_day.hour == 17)):
                    next_non_holiday_day += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_non_holiday_day.strftime('%Y-%m-%d %H:%M')
            elif (date.weekday() < 5 and date.hour >= 9 and date.hour <= 17):
                next_two_days = date + pd.Timedelta(days=2)
                while not ((next_two_days.weekday() < 5) and (next_two_days.hour == 17)):
                    next_two_days += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_two_days.strftime('%Y-%m-%d %H:%M')
            elif (date.weekday() < 5 and date.hour >= 18 and date.hour <= 23):
                next_non_holiday_day = date + pd.Timedelta(days=1)
                while not ((next_non_holiday_day.weekday() < 5) and (next_non_holiday_day.hour == 17)):
                    next_non_holiday_day += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_non_holiday_day.strftime('%Y-%m-%d %H:%M')
            
    return df

Criteria 2: Date within Specific Time Range

If the date falls within a specific time range (e.g., between 9 AM and 5 PM), we need to set the deadline to the next business day at 17:00 hours.

# Define the start and end times of the workday
start_time = pd.Timedelta(hours=9)
end_time = pd.Timedelta(hours=17)

# Calculate deadlines based on dates within specific time ranges
def calculate_deadlines(df):
    df['Deadline'] = ''
    
    for index, row in df.iterrows():
        date = row['Date']
        
        # Check if the date is a holiday or weekend
        if (date.weekday() < 5 and date.hour >= 0 and date.hour <= 8):
            next_non_holiday_day = date + pd.Timedelta(days=1)
            while not ((next_non_holiday_day.weekday() < 5) and (next_non_holiday_day.hour == 17)):
                next_non_holiday_day += pd.Timedelta(days=1)
            
            df.at[index, 'Deadline'] = next_non_holiday_day.strftime('%Y-%m-%d %H:%M')
        elif (date.weekday() < 5 and date.hour >= 9 and date.hour <= 17):
            next_two_days = date + pd.Timedelta(days=2)
            while not ((next_two_days.weekday() < 5) and (next_two_days.hour == 17)):
                next_two_days += pd.Timedelta(days=1)
            
            df.at[index, 'Deadline'] = next_two_days.strftime('%Y-%m-%d %H:%M')
        elif (date.weekday() < 5 and date.hour >= 18 and date.hour <= 23):
            next_non_holiday_day = date + pd.Timedelta(days=1)
            while not ((next_non_holiday_day.weekday() < 5) and (next_non_holiday_day.hour == 17)):
                next_non_holiday_day += pd.Timedelta(days=1)
            
            df.at[index, 'Deadline'] = next_non_holiday_day.strftime('%Y-%m-%d %H:%M')
        
    return df

Criteria 3: Holiday or Weekend

We’ll repeat the same process as in Criteria 1.

# Define a function to check if a day is a holiday or weekend
def is_holiday_or_weekend(date):
    return date in Holidays or date.weekday() in weekend_days

# Calculate deadlines based on holidays and weekends
def calculate_deadlines(df):
    df['Deadline'] = ''
    
    for index, row in df.iterrows():
        date = row['Date']
        
        # Check if the date is a holiday or weekend
        if is_holiday_or_weekend(date):
            next_business_day = date + pd.Timedelta(days=1)
            while not (next_business_day.weekday() < 5 and next_business_day.hour == 17):
                next_business_day += pd.Timedelta(days=1)
            
            df.at[index, 'Deadline'] = next_business_day.strftime('%Y-%m-%d %H:%M')
        else:
            # Calculate the deadline for dates within specific time ranges
            if (date.weekday() < 5 and date.hour >= 0 and date.hour <= 8):
                next_non_holiday_day = date + pd.Timedelta(days=1)
                while not ((next_non_holiday_day.weekday() < 5) and (next_non_holiday_day.hour == 17)):
                    next_non_holiday_day += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_non_holiday_day.strftime('%Y-%m-%d %H:%M')
            elif (date.weekday() < 5 and date.hour >= 9 and date.hour <= 17):
                next_two_days = date + pd.Timedelta(days=2)
                while not ((next_two_days.weekday() < 5) and (next_two_days.hour == 17)):
                    next_two_days += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_two_days.strftime('%Y-%m-%d %H:%M')
            elif (date.weekday() < 5 and date.hour >= 18 and date.hour <= 23):
                next_non_holiday_day = date + pd.Timedelta(days=1)
                while not ((next_non_holiday_day.weekday() < 5) and (next_non_holiday_day.hour == 17)):
                    next_non_holiday_day += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_non_holiday_day.strftime('%Y-%m-%d %H:%M')
            
    return df

Final Calculations

We’ll call the calculate_deadlines function with the input data.

# Load the data
import pandas as pd
from sklearn.model_selection import train_test_split

# Create a sample dataset
data = {
    'Date': ['2022-01-01', '2022-01-02', '2022-01-03'],
    'Start Time': [9, 10, 11],
    'End Time': [17, 18, 19]
}

# Create a DataFrame
df = pd.DataFrame(data)

# Calculate the deadlines
def calculate_deadlines(df):
    df['Deadline'] = ''
    
    for index, row in df.iterrows():
        date = row['Date']
        
        # Check if the date is a holiday or weekend
        if (date.weekday() < 5 and row['Start Time'].hour >= 9 and row['Start Time'].hour <= 17):
            next_business_day = date + pd.Timedelta(days=1)
            while not (next_business_day.weekday() < 5 and next_business_day.hour == 17):
                next_business_day += pd.Timedelta(days=1)
            
            df.at[index, 'Deadline'] = next_business_day.strftime('%Y-%m-%d %H:%M')
        else:
            # Calculate the deadline for dates within specific time ranges
            if (date.weekday() < 5 and date.hour >= 0 and date.hour <= 8):
                next_non_holiday_day = date + pd.Timedelta(days=1)
                while not ((next_non_holiday_day.weekday() < 5) and (next_non_holiday_day.hour == 17)):
                    next_non_holiday_day += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_non_holiday_day.strftime('%Y-%m-%d %H:%M')
            elif (date.weekday() < 5 and date.hour >= 9 and date.hour <= 17):
                next_two_days = date + pd.Timedelta(days=2)
                while not ((next_two_days.weekday() < 5) and (next_two_days.hour == 17)):
                    next_two_days += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_two_days.strftime('%Y-%m-%d %H:%M')
            elif (date.weekday() < 5 and date.hour >= 18 and date.hour <= 23):
                next_non_holiday_day = date + pd.Timedelta(days=1)
                while not ((next_non_holiday_day.weekday() < 5) and (next_non_holiday_day.hour == 17)):
                    next_non_holiday_day += pd.Timedelta(days=1)
                
                df.at[index, 'Deadline'] = next_non_holiday_day.strftime('%Y-%m-%d %H:%M')
            
    return df

# Calculate the deadlines
df['Deadline'] = calculate_deadlines(df)

# Print the results
print(df)

The final answer is: $\boxed{2022-01-02 17:00}$


Last modified on 2024-01-09