パソコン仕事5倍塾
35,000人を指導した東大卒・元日本IBM社内講師が直伝
MENU
たかちゃんさんの投稿
(投稿ID: 5356)
from datetime import datetime, timedelta print("あなたの勤務時間、深夜勤務時間を計算します。(深夜勤務は22:00-5:00までの勤務)") s_input_time = input('開始時刻を入力して下さい。例:8時15分の場合、8:15') e_input_time = input('終了時刻を入力して下さい。例:8時15分の場合、8:15') s_time = datetime.strptime(s_input_time, '%H:%M') e_time = datetime.strptime(e_input_time, '%H:%M') b_time = timedelta(hours=1) ten_pm = datetime.strptime("22:00", '%H:%M') five_am = datetime.strptime("5:00", '%H:%M') #深夜勤務対応処理 if e_time < s_time: e_time = e_time + timedelta(days=1) #深夜勤務の判定 if ten_pm <= s_time or s_time < five_am or ten_pm <= e_time or e_time < five_am: print("深夜勤務です。") #深夜手当対象時間:22:00〜5:00の間 if ten_pm > s_time and ten_pm <= e_time: night_work = e_time - ten_pm print(f"深夜手当対象は、{night_work}時間です。") elif ten_pm <= s_time and ten_pm <= e_time: night_work = e_time - s_time print(f"深夜手当対象は、{night_work}時間です。") elif ten_pm <= s_time and e_time <= five_am: night_work = e_time - s_time print(f"深夜手当対象は、{night_work}時間です。") elif s_time <= five_am and e_time <= five_am: night_work = e_time - s_time print(f"深夜手当対象は、{night_work}時間です。") elif s_time <= five_am and e_time > five_am: night_work = five_am - s_time print(f"深夜手当対象は、{night_work}時間です。") #intervalは、timedelta interval = e_time - s_time #intervalの時間を求める interval_hours = interval.total_seconds() // 60 // 60 #勤務時間が6時間以上の場合、勤務時間から1時間(休憩時間)を引く if interval_hours >= 6: interval = interval -b_time print("6時間以上なので、勤務時間から休憩時間(1時間)をひきます。") print(f"あなたの勤務時間は{interval}です。")
小川 慶一さんのコメント
(コメントID: 7711)
(コメントID: 7758)
""" 勤務時間を計算する。 また、その勤務時間のうち、深夜勤務時間を計算する。深夜勤務は22:00-5:00までの勤務。 前提: 24時間以上の連続勤務はない。 勤務開始時間は22:00以前。 深夜勤務になった場合は、勤務終了時間は5:00以前。 """ from datetime import datetime, timedelta print("あなたの勤務時間、深夜勤務時間を計算します。(深夜勤務は22:00-5:00までの勤務)") s_input_time = input('開始時刻を入力して下さい。例:8時15分の場合、8:15') e_input_time = input('終了時刻を入力して下さい。例:8時15分の場合、8:15') s_time = datetime.strptime(s_input_time, '%H:%M') e_time = datetime.strptime(e_input_time, '%H:%M') if e_time < s_time: e_time = e_time + timedelta(days=1) duration = e_time - s_time if duration.total_seconds() // 60 // 60 >= 6: print("6時間以上なので、勤務時間から休憩時間(1時間)をひきます。") duration += timedelta(hours=1) hours, minutes = int(duration.total_seconds() // 60 // 60), int(duration.total_seconds() // 60 % 60) print(f"あなたの勤務時間は{hours}時間{minutes}分です。") # 時間外勤務時間を算出する ten_pm = datetime.strptime("22:00", '%H:%M') if e_time > ten_pm: midnight_duration = e_time - ten_pm else: midnight_duration = 0 hours, minutes = int(midnight_duration.total_seconds() // 60 // 60), int(midnight_duration.total_seconds() // 60 % 60) print(f"あなたの深夜勤務時間は{hours}時間{minutes}分です。")
たかちゃんさんのコメント
(コメントID: 7783)
(コメントID: 7784)
from datetime import datetime, timedelta """ 勤務時間と深夜手当時間を計算します。 前提条件: 深夜手当時間帯(22:00〜5:00)を含む勤務時間を計算します。 日中勤務は9:00-18:00は対象外。 """ print("勤務時間、深夜勤務時間を計算します。(深夜勤務は22:00-5:00までの勤務)") s_input_time = input('開始時刻を入力して下さい。例:21時30分の場合、21:30--->') e_input_time = input('終了時刻を入力して下さい。例:0時00分の場合、0:00--->') s_time = datetime.strptime(s_input_time, '%H:%M') e_time = datetime.strptime(e_input_time, '%H:%M') ten_pm = datetime.strptime("22:00", '%H:%M') five_am = datetime.strptime("5:00", '%H:%M') + timedelta(days=1) #深夜勤務対応処理 # 21:00-9:00(翌日)のパターンと1:00-4:30,4:30-7:00のようなパターン用 # 作業終了時間は翌日のお昼を超える事はないので、12:00以下の時間なら1日足して翌日とします。 if e_time < s_time: e_time = e_time + timedelta(days=1) elif s_time <= datetime.strptime("12:00", '%H:%M') and e_time <= datetime.strptime("12:00", '%H:%M') : s_time = s_time + timedelta(days=1) e_time = e_time + timedelta(days=1) duration = e_time - s_time if duration.total_seconds() // 60 // 60 >= 6: print("6時間以上なので、勤務時間から休憩時間(1時間)をひきます。") duration -= timedelta(hours=1) hours, minutes = int(duration.total_seconds() // 60 // 60), int(duration.total_seconds() // 60 % 60) print(f"あなたの勤務時間は{hours}時間{minutes}分です。") # 深夜勤務の判定 # ①開始時間も終了時間も[22:00-5:00内]の場合 # ②開始時間は22:00以前、終了時間が[22:00-5:00内]の場合 # ③開始時間は[22:00-5:00内]、終了時間が5:00以降の場合 # ④21:00-9:00のようなパターン([22:00-5:00内]が含まれる夜勤) if ten_pm <= s_time <= five_am and ten_pm <= e_time <= five_am: duration = e_time - s_time if duration.total_seconds() // 60 // 60 >= 6: duration -= timedelta(hours=1) elif s_time < ten_pm and ten_pm <= e_time <= five_am: duration = e_time - ten_pm if duration.total_seconds() // 60 // 60 >= 6: duration -= timedelta(hours=1) elif ten_pm <= s_time <= five_am and e_time > five_am: duration = five_am - s_time if duration.total_seconds() // 60 // 60 >= 6: duration -= timedelta(hours=1) else: duration = datetime.strptime("6:00", '%H:%M').time() print(f'深夜手当時間は、{duration}です。')
(コメントID: 7785)
(コメントID: 7786)
(コメントID: 7787)
(コメントID: 7791)
""" 勤務時間と深夜手当時間を計算します。 前提条件: 深夜手当時間帯(22:00〜5:00)を含む勤務時間を計算します。 日中勤務は9:00-18:00は対象外。 """ from datetime import datetime, timedelta print("勤務時間、深夜勤務時間を計算します。(深夜勤務は22:00-5:00までの勤務)") s_input_time = input('開始時刻を入力して下さい。例:21時30分の場合、21:30--->') e_input_time = input('終了時刻を入力して下さい。例:0時00分の場合、0:00--->') s_time = datetime.strptime(s_input_time, '%H:%M') e_time = datetime.strptime(e_input_time, '%H:%M') ten_pm = datetime.strptime("22:00", '%H:%M') five_am = datetime.strptime("5:00", '%H:%M') + timedelta(days=1) # 深夜勤務用日付の調整(def check_date) # 21:00-9:00(翌日)のパターンと1:00-4:30,4:30-7:00のようなパターン用 # 作業終了時間は翌日のお昼を超える事はないので、12:00以下の時間なら1日足して翌日とします。 def check_date(s_time, e_time): if e_time < s_time: return s_time, e_time + timedelta(days=1) elif s_time <= datetime.strptime("12:00", '%H:%M') and e_time <= datetime.strptime("12:00", '%H:%M') : return s_time + timedelta(days=1), e_time + timedelta(days=1) else: return s_time, e_time # check_dateで調整した値を2つタプルで受け取り se_time_tuple = check_date(s_time, e_time) print(f'日付変換後の結果:{se_time_tuple}') s_time = se_time_tuple[0] e_time = se_time_tuple[1] # 深夜勤務の判定 # ①開始時間も終了時間も[22:00-5:00内]の場合 # ②開始時間は22:00以前、終了時間が[22:00-5:00内]の場合 # ③開始時間は[22:00-5:00内]、終了時間が5:00以降の場合 # ④21:00-9:00のようなパターン([22:00-5:00内]が含まれる夜勤) def night_work_check(s_time, e_time): if ten_pm <= s_time <= five_am and ten_pm <= e_time <= five_am: duration = e_time - s_time if duration.total_seconds() // 60 // 60 >= 6: return duration - timedelta(hours=1) else: return duration elif s_time < ten_pm and ten_pm <= e_time <= five_am: duration = e_time - ten_pm if duration.total_seconds() // 60 // 60 >= 6: return datetime.strptime("6:00", '%H:%M').time() else: return duration elif ten_pm <= s_time <= five_am and e_time > five_am: duration = five_am - s_time if duration.total_seconds() // 60 // 60 >= 6: return datetime.strptime("6:00", '%H:%M').time() else: return duration else: return datetime.strptime("6:00", '%H:%M').time() # 結果出力 duration = e_time - s_time if duration.total_seconds() // 60 // 60 >= 6: print("6時間以上なので、勤務時間から休憩時間(1時間)をひきます。") duration -= timedelta(hours=1) hours, minutes = int(duration.total_seconds() // 60 // 60), int(duration.total_seconds() // 60 % 60) print(f"あなたの勤務時間は{hours}時間{minutes}分です。") nw_time = night_work_check(s_time, e_time) print(f'深夜手当時間は、{nw_time}です。')
(コメントID: 7795)
""" 勤務時間と深夜手当時間を計算します。 前提条件: 深夜手当時間帯(22:00〜5:00)を含む勤務時間を計算します。 日中勤務は9:00-18:00は対象外。 """ from datetime import datetime, timedelta MID_FROM = datetime.strptime("22:00", '%H:%M') MID_TO = datetime.strptime("5:00", '%H:%M') + timedelta(days=1) BEFORE_MID = 0 WITHIN_MID = 1 AFTER_MID = 2 def get_wrapped_start_and_end_datetime(s_input_time, e_input_time): """ 勤務終了日が翌日となる場合を考慮した計算用の勤務終了時間を取得する :param s_input_time: 入力された勤務開始時間文字列 :param e_input_time: 入力された勤務終了時間文字列 :return: 計算用の日付時刻 s_time, e_time のタプル。 """ s_time = datetime.strptime(s_input_time, '%H:%M') e_time = datetime.strptime(e_input_time, '%H:%M') if e_time < s_time: e_time = e_time + timedelta(days=1) elif s_time <= datetime.strptime("12:00", '%H:%M') and e_time <= datetime.strptime("12:00", '%H:%M'): s_time = s_time + timedelta(days=1) e_time = e_time + timedelta(days=1) return s_time, e_time def get_duration(s_time, e_time): """ 実質労働時間を判定する 6時間を超えた場合は1時間の休憩があったとみなす :param s_time: 勤務開始時間 :param e_time: 勤務終了時間 :return: 以下の2つの要素の tuple 実質労働時間。 timedelta 型 1時間分の休憩を引いたかどうか(引いた場合 True) """ duration = e_time - s_time subtracted = False if duration.total_seconds() // 60 // 60 >= 6: subtracted = True duration -= timedelta(hours=1) return duration, subtracted def get_labor_hour_type(dt): """ 勤務時間帯を評価した値を返す -22:00: BEFORE_MID = 0 22:00-05:00: WITHIN_MID = 1 05:00- : AFTER_MID = 2 """ if dt < MID_FROM: return BEFORE_MID if dt < MID_TO: return WITHIN_MID return AFTER_MID def get_midnight_work_hours(s_time, e_time): """ 勤務開始時間、終了時間から、時間外労働時間を算出する :param s_time: 勤務開始日時 :param e_time: 勤務終了日時。日付部分が s_time の翌日の場合がある :return: """ if s_time >= e_time: raise ValueError('勤務終了日時が開始日時より前の値です') s_time_type = get_labor_hour_type(s_time) e_time_type = get_labor_hour_type(e_time) if s_time_type == BEFORE_MID: # 通常労働時間から業務開始 if e_time_type == BEFORE_MID: # 深夜にいっさい絡まない return timedelta(seconds=0) elif e_time_type == WITHIN_MID: # 開始は通常。終了は深夜。22:00-以降の分が深夜 return e_time - MID_FROM else: # 深夜勤務時間をまるまる含む return MID_TO - MID_FROM elif s_time_type == WITHIN_MID: # 深夜労働時間から業務開始 if e_time_type == BEFORE_MID: # 全体の流れからして、ここに来ることはありえない raise ValueError('開始時間、終了時間が不正です') elif e_time_type == WITHIN_MID: # 深夜時間に開始、深夜時間に終了 return e_time - s_time else: # 勤務開始時間から 5:00 まではまるまる深夜時間 return MID_TO - s_time else: # 翌朝朝5:00以降に勤務開始。 # ここに来ることはありえない raise ValueError('勤務開始日の値が不正です') print("勤務時間、深夜勤務時間を計算します。(深夜勤務は22:00-5:00までの勤務)") s_input_time = input('開始時刻を入力して下さい。例:21時30分の場合、21:30--->') e_input_time = input('終了時刻を入力して下さい。例:0時00分の場合、0:00--->') s_time, e_time = get_wrapped_start_and_end_datetime(s_input_time, e_input_time) duration, subtracted = get_duration(s_time, e_time) if subtracted: print("6時間以上なので、勤務時間から休憩時間(1時間)をひきます。") hours, minutes = int(duration.total_seconds() // 60 // 60), int(duration.total_seconds() // 60 % 60) print(f"あなたの勤務時間は{hours}時間{minutes}分です。") midnight_work_hours = get_midnight_work_hours(s_time, e_time) print(f'深夜手当時間は、{midnight_work_hours}です。')
(コメントID: 7797)
Captcha:
たった1ヶ月で人生が劇的に変わりました
佐藤信さん
役員クラスの方から高い評価を受けるようになりました。
佐賀県 - 岩本徹さん
今までまったく知らなかったショートカットキーを使いまくっています。
東京都 - 鷹觜慶さん
年齢60才間近、営業で外回りの時間が多い私でも退社時間が1-2時間程度早くなりました。
東京都 - 宗内隆明さん
受講前もすでにパソコン得意でしたが、そんな私でも受講して本当に良かったと思えた講座です。
東京都 - 佐伯とも子さん
ここまで包括的に仕事に役立つ深い学びを受けれた講座は初めてでした
東京都 - 飯田倫子さん
2025年03月13日 10:11
2025年03月12日 00:12
2025年02月26日 08:51
2025年02月25日 00:11
2025年02月13日 08:06
2025年03月13日 10:27
2025年03月13日 10:17
2025年03月12日 22:46
2025年03月12日 07:41
2022年02月24日 10:59
表示できる投稿はありません。
この学習サイトの教材制作、サポート、システム開発をすべてやっています。
2022年02月02日 00:00
2022年02月02日 03:00
2022年02月02日 06:00
2022年02月02日 09:00
2022年02月02日 12:00
2025年02月28日 09:44
2024年12月19日 11:30
2024年12月18日 13:30
2024年10月21日 17:30
2024年10月18日 17:00
2025年02月04日 08:51
2025年02月03日 12:58
2024年11月27日 11:48
2024年11月25日 12:07
2024年11月17日 09:51
2025年03月14日 21:18
2025年03月14日 00:25
2025年03月13日 00:17
2025年02月26日 23:24
2025年02月25日 23:32
2025年03月15日 13:24
2025年03月15日 13:23
2025年02月26日 16:37
2025年02月24日 15:44
2025年02月24日 15:42
2025年03月04日 22:18
2025年03月02日 14:34
2025年02月27日 22:25
2025年02月26日 00:04
2025年02月24日 23:16
2025年03月08日 07:15
2025年03月04日 15:36
2025年02月26日 16:38
2025年02月26日 16:36
2025年02月24日 22:57
たかちゃんさんの投稿
(投稿ID: 5356)
小川 慶一さんのコメント
(コメントID: 7711)
インターフェイスが command line ですが、ウェブブラウザから入力するようになったら、ちょっとしたツールにとして使えそうですね (^^
小川 慶一さんのコメント
(コメントID: 7758)
単純に、以下の感じで良いのかなとも思うのですが、どうでしょう。
朝5時以降も勤務が続いた分についても計算し直すならば、以下で、変数 midnight_duration の値から引き算する感じです。
似たような処理になるので、関数を作ってそこで処理を抽象化すれば洗練されたコードになるかと。
たかちゃんさんのコメント
(コメントID: 7783)
すみません、本日気づきました。m(_ _)m
工事会社ではよくあるパターンの計算でして、
作業時間は2時間だったりすることも・・・・(短)日中・深夜関係なく工事が行われるので結構複雑です。(><)
因みに、作業時間が何時間だろうが一定額のお給料は支給されますが、作業時間は別に記録しておくシステムとなっています。
深夜手当時間だけは、22:00-5:00に働いた分が別途支給です。
頂いたアドバイスを元に、簡素化してみました。
また、プログラム書き終わった所で投稿します。(^^;)
If 22:00<=開始時間<=5:00 and 22:00<=終了時間<= 5:00の場合
深夜手当時間=終了時間-開始時間(②、③、④)
Elseif 開始時間>終了時間
深夜手当時間=6:00(⑥)
If 開始時間<22:00 and 22:00<= 終了時間<=0:00の間の場合(①)
深夜手当=終了時間-22:00
Else
0:00<= 開始時間<= 5:00 and 終了時間>5:00の場合(⑤)
深夜手当=5:00-開始時間
ーーーー
ルール:
・時間は30分単位
・勤務時間が6時間以上になったら、休憩時間1時間分ひく。
・深夜手当が支給される時間は、22:00〜5:00に働いた時間。(但し、最大で6時間分までの支給。)
・8時間超えた分は残業時間。
深夜勤務のパターン
①21:00〜22:30(深夜手当時間:0:30)
②22:00〜22:30(深夜手当時間:0:30)
③22:30〜4:30(深夜手当時間:5:00)
④1:00〜4:30(深夜手当時間:3:30)
⑤4:30〜7:00(深夜手当時間:0:30)
⑥21:00〜9:00(深夜手当時間:6:00)
ーーーー
たかちゃんさんのコメント
(コメントID: 7784)
あとは、関数を使ってまとめれば良さそうです・・・。
はまった箇所:
①深夜手当時間の計算で、「22:00-0:00」と「0:00-5:00」を分けて考えていたのですが、datetimeには日付データもある為
分けて考える必要がなかった事。(単純に、終了時刻-開始時刻の引き算で良い。)
②duration = datetime.strptime("6:00", '%H:%M').time() 最後に、「.time()」を付けると時刻のみ表示される事。
ややこしくて申し訳ないですが、記念に投稿させて下さい。(T T)
小川 慶一さんのコメント
(コメントID: 7785)
関数等使ってプラッシュアップしたものを作ったら、またアップしてください。
僕も、いただいたコードをいろいろ手直ししてみました。
そのときに、僕の書いたコードをお見せしたいと思います (^^
小川 慶一さんのコメント
(コメントID: 7786)
以下のサンプルのような感じで。
ref: https://peps.python.org/pep-0008/#module-level-dunder-names
たかちゃんさんのコメント
(コメントID: 7787)
docstringの件もありがとうございます。
完成後、再び投稿します。
たかちゃんさんのコメント
(コメントID: 7791)
「深夜勤務日付調整」と「深夜手当時間IF文」の2箇所で関数を作成しました。
ポイント:
①def check_dateでは、値を2つ関数に渡して、結果を2つ受け取っています。
結果はタプルになって受け取る事が分かりました。
②以下の条件で、深夜手当時間が6:00以上になった場合は、6:00を返すように
記述を変更しました。(前回までは、マイナス1:00時間としていた。)
<条件>
②開始時間は22:00以前、終了時間が[22:00-5:00内]の場合
③開始時間は[22:00-5:00内]、終了時間が5:00以降の場合
小川 慶一さんのコメント
(コメントID: 7795)
以下については、配慮していません。
>②以下の条件で、深夜手当時間が6:00以上になった場合は、6:00を返すように
> 記述を変更しました。(前回までは、マイナス1:00時間としていた。)
> <条件>
> ②開始時間は22:00以前、終了時間が[22:00-5:00内]の場合
> ③開始時間は[22:00-5:00内]、終了時間が5:00以降の場合
ところで、「作業終了時間は翌日のお昼を超える事はない」ということですが、「勤務時間の開始と終了は深夜で深夜勤務時間が6時間を超える」という状況がありえるのでしょうか。
あるとしたら、1:00-23:00, 2:00-24:00, 3:00-25:00, 4:00-26:00 等が相当しますが。
これらがありえないのであれば、条件分岐はそんなに難しくなさそう。
あと、単純に深夜勤務手当の最大値は 6:00 ということであれば、いったん深夜の実労働時間を計算して、それと 6:00 とを比較して大きい方を取るとか。
以下では、定数や関数は別モジュールに置いて import で呼び出したほうがスッキリするかなと思います。
そろそろ、モジュールとインポート文の話をきちんとするべきかなと思ってます。あと、テストコードの書き方を。
たかちゃんさんのコメント
(コメントID: 7797)
コードを拝見しました。
頭に叩き込むには少し時間がかかりそうですが、写経して少しづ習得したいと思います。
本当にありがとうございます。m(_ _)m
特に、以下がとても参考になりました。自分でコードを書いていた時は、どこかの条件が抜けていそうな混乱した状態でした。
①各処理は、関数で設定。
②複雑な評価の場合は、
BEFORE_MID、WITHIN_MID、 AFTER_MIDと評価基準を作成しておく。
③判定する値も複数ある場合は、
まずは、1つ(開始時間)の評価をIF文で書いて、その隙間に、2つ目(終了時間)の判定し処理を書く。
④get_midnight_work_hoursの処理の中で、get_labor_hours_typeを呼び出していましたが
このような動きが可能だという事に気づきました。
ーーー
>ところで、「作業終了時間は翌日のお昼を超える事はない」ということですが、「勤務時間の開始と終了は深夜で深夜勤務時間が6時間を超え
>る」という状況がありえるのでしょうか。
>あるとしたら、1:00-23:00, 2:00-24:00, 3:00-25:00, 4:00-26:00 等が相当しますが。
>これらがありえないのであれば、条件分岐はそんなに難しくなさそう。
8月1日 1:00a.m. 〜8月2日21:00p.m.のパターンでしょうか。
このような状況はありません。
作業時間が長くても、12-13時間程度で以下のような感じです。
8月1日(16:00p.m.)開始し、8月2日(4:00a.m)に終了
8月1日(21:00p.m.)開始し、8月2日(8:00.a.m.)に終了
色々、ありがとうございます。m(_ _)m
ーーー