Làm cách nào để tính ngày làm việc bằng Python trừ ngày nghỉ cuối tuần và ngày lễ?

Lịch thường là chất keo giữ cho cuộc sống bận rộn của chúng ta được khéo léo. Nhưng nếu tổ chức của bạn chỉ cần xem xét ngày làm việc trong ứng dụng của bạn thì sao?

Kiểm tra sự cố của anh ấy dưới đây

Hàm DateDiff cho phép ứng dụng tính toán chênh lệch giữa hai ngày – một thao tác lịch đơn giản. Tuy nhiên, trong nhiều ứng dụng kinh doanh, người ta cần loại bỏ các ngày cuối tuần khi nhận được sự khác biệt – ứng dụng cần biết có bao nhiêu ngày làm việc giữa hai ngày nhất định. Có một vài chủ đề trong các diễn đàn có cùng một vấn đề, vì vậy tôi quyết định viết một bài chi tiết với giải pháp cho vấn đề này

không bao gồm các ngày cuối tuần

Phần đầu tiên của bài toán tính chênh lệch số ngày làm việc là loại trừ các ngày cuối tuần trong phép tính. Để bắt đầu, trước tiên chúng ta cần tính số tuần giữa hai ngày, mà chúng ta có thể nhận được bằng cách lấy toàn bộ phần của phép chia [sử dụng hàm RoundDown] của chênh lệch ngày “thô” cho 7

RoundDown[DateDiff[StartDate.SelectedDate, EndDate.SelectedDate, Days] / 7, 0]

Và sau đó là sự khác biệt của những ngày không phải trong cả tuần. Để làm được điều đó, chúng ta cần sử dụng hàm Weekday. Trong hàm bên dưới, nếu ngày bắt đầu và ngày kết thúc nằm trong khoảng từ Thứ Hai đến Thứ Sáu [các ngày trong tuần từ 2 đến 6], chênh lệch của chúng sẽ là -4 [bắt đầu vào Thứ Sáu, kết thúc vào Thứ Hai] đến 4 [bắt đầu vào Thứ Hai, kết thúc vào

Mod[5 + Weekday[EndDate.SelectedDate] - Weekday[StartDate.SelectedDate], 5]

Đặt tất cả lại với nhau, chúng ta có số ngày, không kể ngày cuối tuần, giữa hai ngày là số tuần nhân 5 [ngày mỗi tuần], cộng với số ngày trong một phần tuần

RoundDown[DateDiff[StartDate.SelectedDate, EndDate.SelectedDate, Days] / 7, 0] * 5 +
Mod[5 + Weekday[EndDate.SelectedDate] - Weekday[StartDate.SelectedDate], 5]

Lưu ý rằng phép tính một phần tuần được đưa ra ở trên sẽ không hoạt động nếu ngày bắt đầu hoặc ngày kết thúc rơi vào cuối tuần;

Đối phó với ngày lễ

Ngày lễ không phải là thứ mà chúng ta có thể tìm thấy một công thức chung – mỗi quốc gia [hoặc khu vực trong một quốc gia] có danh sách ngày lễ riêng. Để giải thích cho điều đó sau đó, chúng ta cần có thông tin về các ngày lễ được lưu trữ ở đâu đó [e. g. , trong tệp Excel, trong bảng cơ sở dữ liệu SQL, v.v. ] để chúng ta có thể sử dụng nó trong logic của mình. Trong ví dụ này, tôi sẽ sử dụng bảng Excel với các ngày lễ ở Hoa Kỳ

Sau khi bảng đó được nhập vào ứng dụng [trong trường hợp của tôi là Holidays2017], thì chúng ta có thể sử dụng hàm CountIf để xác định có bao nhiêu ngày lễ trong số đó nằm trong phạm vi ngày của chúng ta

Một cách để lấy danh sách ngày làm việc giữa hai ngày trong gấu trúc là sử dụng hàm bdate_range[]

Điều đáng chú ý là chức năng này chỉ đếm số ngày giữa ngày bắt đầu và ngày kết thúc, không bao gồm ngày cuối tuần

Ví dụ: chúng ta có thể sử dụng cú pháp sau để đếm số ngày làm việc trong khoảng thời gian từ 1/1/2022 đến 31/12/2022

import pandas as pd

#get all business days between certain start and end dates
business_days = pd.bdate_range['2022-01-01', '2022-12-31']

#view first ten business days
print[business_days[0:10]]

DatetimeIndex[['2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06',
               '2022-01-07', '2022-01-10', '2022-01-11', '2022-01-12',
               '2022-01-13', '2022-01-14'],
              dtype='datetime64[ns]', freq='B']

#view total number of business days
len[business_days]

260

Đối tượng được gọi là business_days chứa mọi ngày làm việc giữa ngày bắt đầu và ngày kết thúc được chỉ định

Và bằng cách sử dụng hàm len[], chúng ta thấy rằng tổng số ngày làm việc giữa ngày bắt đầu và ngày kết thúc được chỉ định là 250

Ngày bắt đầuNgày kết thúc02019-06-032019-08-3112019-06-132019-06-2122019-10-012019-10-2532019-09-012019-12-25

Danh sách ngày lễ tùy chỉnh

holiday_dates = [pd.datetime[2019, 8, 15], pd.datetime[2019, 10, 2], pd.datetime[2019, 10, 8],
                 pd.datetime[2019, 10, 28], pd.datetime[2019, 12, 25]]

Ví dụ - tính ngày làm việc [không kể ngày nghỉ cuối tuần] với các ngày lễ tùy chỉnh

# Exclude weekends and custom holidays
pd.bdate_range[pd.datetime[2019, 8, 1], pd.datetime[2019, 8, 31],  holidays=holiday_dates, freq='C', weekmask = None]

DatetimeIndex[['2019-08-01', '2019-08-02', '2019-08-05', '2019-08-06',
               '2019-08-07', '2019-08-08', '2019-08-09', '2019-08-12',
               '2019-08-13', '2019-08-14', '2019-08-16', '2019-08-19',
               '2019-08-20', '2019-08-21', '2019-08-22', '2019-08-23',
               '2019-08-26', '2019-08-27', '2019-08-28', '2019-08-29',
               '2019-08-30'],
              dtype='datetime64[ns]', freq='C']

Áp dụng tương tự bằng cách sử dụng lambda

data['Business Days'] = data.apply[lambda x: len[pd.bdate_range[x['Start Date'],
                                                                x['End Date'],
                                                                holidays=holiday_dates,
                                                                freq='C',
                                                                weekmask = None]], axis = 1]
data

Ngày bắt đầuNgày kết thúcNgày làm việc02019-06-032019-08-316412019-06-132019-06-21722019-10-012019-10-251732019-09-012019-12-2579

Chủ Đề