【Python】各種日付の計算を関数にまとめたもの

2024年8月24日Python

処理概要

日付の計算機能を関数にまとめまています。


与えられた2つの日付データから日数の差を計算して返す

機能概要

  • ファイル名:date_difference.py
  • 関数名:diff
  • 引数
    • date1(str)
    • date2(str)
  • 形式:'yyyy/m/d' または 'yyyy/mm/dd'
  • 戻り値
    • int:日数

コード

from datetime import datetime

def diff(date1: str, date2: str) -> int:
    # 日付をyyyy/m/d形式にする
    date_format = '%Y/%m/%d'

    # 日付を変換してから計算する
    d1 = datetime.strptime(date1, date_format)
    d2 = datetime.strptime(date2, date_format)
    delta = abs((d2 - d1).days)

    return delta

使い方

import date_difference as dd

date1 = '2024/8/5'
date2 = '2024/8/6'
print(dd.diff(date1, date2))

実行結果

1


与えられた2つの日付データからどちらが未来日であるか判定して結果を返す

機能概要

  • ファイル名:compare_dates.py
  • 関数名:compare
  • 引数
    • date1(str)
    • date2(str)
  • 形式:'yyyy/m/d' または 'yyyy/mm/dd'
  • 戻り値
    • str:判定結果のメッセージ

コード

from datetime import datetime

def compare(date1: str, date2: str) -> str:
    # 日付をyyyy/m/d形式にする
    date_format = '%Y/%m/%d'

    # 日付を変換してから比較する
    d1 = datetime.strptime(date1, date_format)
    d2 = datetime.strptime(date2, date_format)

    if d1 > d2:
        return f'{date1} の方が未来日です'
    elif d1 < d2:
        return f'{date2} の方が未来日です'
    else:
        return r'同じ日付です'

使い方①

import compare_dates as cd

date1 = '2024/08/10'
date2 = '2024/08/25'
print(cd.compare(date1, date2))

実行結果①

2024/08/25 の方が未来日です

使い方②

import compare_dates as cd

date1 = '2024/08/25'
date2 = '2024/08/25'
print(cd.compare(date1, date2))

実行結果②

同じ日付です


与えられた日付(未来日)までの営業日を返す関数

機能概要

  • ファイル名:business_days.py
  • 関数名: count
  • 引数
    • file_path (str, pathlib.WindowsPath): Excelファイルのパス
    • future_date (str): 未来日
    • sheet_name (str, optional): シート名
  • 形式: 'yyyy/m/d' または 'yyyy/mm/dd'
  • 戻り値
    • int:未来日から非営業日を減算した日数

インプットとなるExcelファイル

  • ファイル名:non_business_days.xlsx
  • 非営業日の一覧をExcelファイルのA列に記載する
  • シート名の指定がない場合は先頭シートを対象とする
  • A1セルはヘッダ名として 非営業日 を記載する
  • A2セル以降にyyyy/m/d形式で非営業日を記載する

ファイル入力例

コード

import pandas as pd
from datetime import datetime

def non_business_days_read(file_path: str, sheet_name: str = None) -> pd.DataFrame:
    if sheet_name:
        df = pd.read_excel(file_path, sheet_name=sheet_name, usecols='A')
    else:
        df = pd.read_excel(file_path, usecols='A')

    df['非営業日'] = pd.to_datetime(df['非営業日']).dt.strftime('%Y/%m/%d')

    return df

def count(file_path: str, future_date: str, sheet_name: str = None) -> int:
    # Excelファイルから非営業日一覧を取得する
    df = non_business_days_read(file_path, sheet_name)

    # 非営業日をリストに変換する
    non_business_days = pd.to_datetime(df.iloc[:, 0], format='%Y/%m/%d')
    # 未来日を計算可能な形式に変換する
    future_date_obj = datetime.strptime(future_date, '%Y/%m/%d')

    # 非営業日一覧からすでに経過しているものを除く
    non_business_days = non_business_days[non_business_days >= datetime.today()]
    # 未来日までに設定されている非営業日を抽出する
    non_business_days_until_future = non_business_days[non_business_days <= future_date_obj]
    # 残った非営業日数
    non_business_days_count = len(non_business_days_until_future)

    # 未来日までの日数を計算する ※営業日の考え方で加算日を調整
    total_days = (future_date_obj - datetime.today()).days + 1
    # 非営業日を減算し営業日数を計算する
    business_days = total_days - non_business_days_count

    return business_days

使い方①

2024年8月4日に実行したもの

import business_days as bd
from pathlib import Path

file_path = Path.cwd() / 'non_business_days.xlsx'
future_date = '2024/08/13'
print(bd.count(file_path, future_date))

実行結果①

6

使い方②

シート名(Sheet1)を指定する場合

import business_days as bd
from pathlib import Path

file_path = Path.cwd() / 'non_business_days.xlsx'
sheet_name = 'Sheet1'
future_date = '2024/08/13'
print(bd.count(file_path, future_date, sheet_name))

実行結果②

6


指定した日付から指定した営業日数を引いた日付を返す関数

機能概要

  • ファイル名:business_days.py
  • 関数名: calc_minus
  • 引数
    • file_path (str, pathlib.WindowsPath): Excelファイルのパス
    • target_date (str): ターゲットとなる日付
    • days_to_subtract (int): ターゲットの日付から引く営業日数
    • sheet_name (str, optional): シート名
  • 形式: 'yyyy/m/d' または 'yyyy/mm/dd'
  • 戻り値
    • str: 指定した日付から指定した営業日数を引いた日付

インプットとなるExcelファイル

  • インプットに関してはcountと同じ

コード

import pandas as pd
from datetime import datetime

def non_business_days_read(file_path: str, sheet_name: str = None) -> pd.DataFrame:
    if sheet_name:
        df = pd.read_excel(file_path, sheet_name=sheet_name, usecols='A')
    else:
        df = pd.read_excel(file_path, usecols='A')

    df['非営業日'] = pd.to_datetime(df['非営業日']).dt.strftime('%Y/%m/%d')

    return df

def subtract_business_days(file_path: str, target_date: str, days_to_subtract: int, sheet_name: str = None) -> str:
    # Excelファイルから非営業日一覧を取得する
    df = non_business_days_read(file_path, sheet_name)

    # 非営業日をリストに変換する
    non_business_days = pd.to_datetime(df.iloc[:, 0], format='%Y/%m/%d')
    # 指定する未来日と比較できる形式に変換する
    non_business_days = non_business_days.apply(lambda x: x.strftime('%Y/%m/%d')).tolist()
    target_date_obj = datetime.strptime(target_date, '%Y/%m/%d')

    # 指定日のチェック
    if target_date in non_business_days:
        return r'指定した日付は非営業日です'

    # 営業日数を計算
    while business_days_to_subtract > 0:
        target_date_obj -= pd.Timedelta(days=1)
        if target_date_obj.strftime('%Y/%m/%d') not in non_business_days:
            business_days_to_subtract -= 1

    result_date = target_date_obj.strftime('%Y/%m/%d')

    return result_date

使い方①

2024年8月14日の3営業日前の日付を表示する

import business_days as bd
from pathlib import Path

file_path = Path.cwd() / 'non_business_days.xlsx'
target_date = '2024/08/14'
days_to_subtract = 3
print(bd.calc_minus(file_path, target_date, days_to_subtract))

実行結果①

2024/08/08

使い方②

シート名(Sheet1)を指定する場合

import business_days as bd
from pathlib import Path

file_path = Path.cwd() / 'non_business_days.xlsx'
sheet_name = 'Sheet1'
target_date = '2024/08/14'
days_to_subtract = 3
print(bd.calc_minus(file_path, target_date, days_to_subtract, sheet_name))

実行結果②

2024/08/08

Python

Posted by junichi