0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

問い合わせの返信遅れをPythonで検出、営業時間で数える

0
Posted at

今日、架空の問い合わせを計算すると、金曜夕方から月曜朝まで「65時間」。営業時間では60分でした。僕なら返信遅れはこの60分で判定します。夜間も足すと、週末を挟んだ案件が上に来るからです。

受付から初回返信まで、未返信は集計時刻まで数えます。

引き算だけでは週末も昼休みも入る

平日9〜12時と13〜17時の窓口で、4営業時間を超えたら要確認とします。9月8日は架空の会社休業日。祝日の自動取得はしません。

受付から返信までの区間と、午前・午後の営業枠が重なる部分だけを足します。開始は遅いほう、終了は早いほう。重なりがなければ0です。

昼休みは営業枠に入れません。「日数×7時間」では、初日と最終日の端が扱えません。

Pythonで4件を数える

reply_clock.pyに保存し、python3 reply_clock.pyで実行。Python 3.14.6で検証済み、追加ライブラリ不要です。日時は日本時間・時差情報なし。

from datetime import datetime as D, date, time, timedelta as T

CLOSED = {date(2026, 9, 8)}  # 架空の会社休業日
AS_OF = D(2026, 9, 10, 15)  # 集計時刻を固定
LIMIT = T(hours=4)

def business_time(start, end):
    if start.tzinfo is not None or end.tzinfo is not None:
        raise ValueError("日時は日本時間・時差情報なしで指定")
    if end < start:
        raise ValueError("終了が受付より前です")
    total = T()
    day = start.date()
    while day <= end.date():
        if day.weekday() < 5 and day not in CLOSED:
            for opening, closing in ((9, 12), (13, 17)):
                left = max(start, D.combine(day, time(opening)))
                right = min(end, D.combine(day, time(closing)))
                total += max(T(), right - left)
        day += T(days=1)
    return total

rows = [
    ("週末", "2026-09-04T16:30", "2026-09-07T09:30"),
    ("昼休み", "2026-09-10T11:30", "2026-09-10T13:30"),
    ("休業日", "2026-09-07T16:30", "2026-09-09T09:30"),
    ("未返信", "2026-09-10T09:30", None),
]
for label, received, replied in rows:
    end = D.fromisoformat(replied) if replied else AS_OF
    elapsed = business_time(D.fromisoformat(received), end)
    status = "要確認" if elapsed > LIMIT else "範囲内"
    print(f"{label}: {elapsed.total_seconds() / 60:g}{status}")
週末: 60分 範囲内
昼休み: 60分 範囲内
休業日: 60分 範囲内
未返信: 270分 要確認

weekday()は月曜が0、日曜が6。標準ライブラリの実装でも確認しました。< 5で平日を選び、会社休業日は別に除きます。

240分の境目も試す

同じファイルの末尾で境目も検証します。

start = D(2026, 9, 10, 9)
assert business_time(start, D(2026, 9, 10, 14)) == LIMIT
assert business_time(start, D(2026, 9, 10, 14, 0, 1)) > LIMIT
assert business_time(start, start) == T()
assert business_time(D(2026, 9, 8, 9), D(2026, 9, 8, 17)) == T()

すべて通りました。240分は範囲内、1秒超えたら要確認。分へ直す前の値で判定します。

未返信を0分にすると、待っている案件が埋もれます。集計時刻AS_OFを固定すれば、後日も再現できる。ここ、地味に効きます。

実務ではrowsを実データへ替え、CLOSEDに休業日を追加。海外拠点や保留時間の除外は対象外です。

僕は未返信で要確認の案件から見る運用にします。担当者を比べるなら、問い合わせの難しさも別に見たい。窓口が増えたら、営業枠を窓口別に持つ必要が出そうです。昼休みも返信時間に含めていますか。コメントで教えてもらえるとうれしいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?