Help us understand the problem. What is going on with this article?

datetimeで嵌るパターン in Python3

TL; DR

  • time同士から直接timedeltaは生成できない。datetime同士のみ。
  • timedelta(0)はFalse判定。if文などでNone判定するときに注意。
  • よりよい方法があればコメント、編集リクエストいただけると嬉しいです。

ある家での会話

timeからtimedelta

J( 'ー`)し「12:00 - 07:00 は?」

( `Д)「はいな(小学生扱いかよ、簡単すぎるやろ)」

import datetime

td = datetime.time(12, 0, 0) - datetime.time(7, 0, 0)

assert(td.total_seconds() == 18000)
print(f'時間差は {td} やで')
実行結果
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'

( `Д)「ふぁっ!?」

J( 'ー`)し「(嵌りやがった)」

J( 'ー`)し「timedeltaはtime同士の引き算からは無理やから、datetime同士使わなあかんねんで」

( `Д)「ほなtime同士でtimedelta求めたい場合はどないしたらええん?」

J( 'ー`)し「適当に日付をつけておくか、秒にして計算するとかちゃう?」

適当に日付をつける場合
import datetime

t1 = datetime.time(7, 0, 0)
t2 = datetime.time(12, 0, 0)

d = datetime.datetime.now().date()
td = datetime.datetime.combine(d, t2) - datetime.datetime.combine(d, t1)

assert(td.total_seconds() == 18000)
秒で計算する場合
import datetime

def total_seconds(t: datetime.time):
    return t.hour * 3600 + t.minute * 60 + t.second

t1 = datetime.time(7, 0, 0)
t2 = datetime.time(12, 0, 0)

td = datetime.timedelta(seconds=total_seconds(t2) - total_seconds(t1))

assert(td.total_seconds() == 18000)

timedeltaが0になる場合はTrue? False?

J( 'ー`)し「時間の引き算する表作ってんけど、たまにNoneがあるねん。Noneのときだけ呼んでくれへん?」

( `Д)「はいはい(めんどくせーな)」

J( 'ー`)し「(こっそりtimedelta(0)仕込んだろ)」

from typing import List
import datetime

def total_seconds(t: datetime.time):
    return t.hour * 3600 + t.minute * 60 + t.second

# データの準備
time_list: List[datetime.timedelta] = [
    None,
    datetime.timedelta(seconds=total_seconds(datetime.time(16, 0, 0)) - total_seconds(datetime.time(9, 0, 0))),
    datetime.timedelta(seconds=total_seconds(datetime.time(14, 0, 0)) - total_seconds(datetime.time(8, 0, 0))),
    datetime.timedelta(seconds=total_seconds(datetime.time(12, 0, 0)) - total_seconds(datetime.time(7, 0, 0))),
    datetime.timedelta(seconds=total_seconds(datetime.time(10, 0, 0)) - total_seconds(datetime.time(6, 0, 0))),
    None,
    datetime.timedelta(seconds=total_seconds(datetime.time(8, 0, 0)) - total_seconds(datetime.time(5, 0, 0))),
    datetime.timedelta(seconds=total_seconds(datetime.time(6, 0, 0)) - total_seconds(datetime.time(4, 0, 0))),
    datetime.timedelta(seconds=total_seconds(datetime.time(4, 0, 0)) - total_seconds(datetime.time(3, 0, 0))),
    datetime.timedelta(seconds=0),  # カーチャンが仕込んだイタズラ
    None,
]

for cnt, td in enumerate(time_list, 1):
    if not td:
        print(f'{cnt} 個目、Noneやで')

( \'Д /)「(なんか datetime.timedelta(seconds=0) あるけど気にせんとこか)」

( `Д)「1個目、6個目、11個目でNoneやで(めんどくせー、はやく実行して終わらしたろ)」

実行結果
1 個目、Noneやで
6 個目、Noneやで
10 個目、Noneやで
11 個目、Noneやで

( `Д)「なんで10個目!?」

J( 'ー`)し「timedelta(0)もFalseになるねんで」

print(bool(None))                            # --> False
print(bool(datetime.timedelta(seconds=1)))   # --> True
print(bool(datetime.timedelta(seconds=0)))   # --> False
print(bool(datetime.timedelta(seconds=-1)))  # --> True

J( 'ー`)し「さっきのif文は、こうせえへんとカーチャンの要求どおりにならへんで」

if td is None:
    print(f'{cnt} 個目、Noneやで')

(´・ω・`)「(参りましたわ…)」

余談

実際の私のカーチャン J( 'ー`)し はプログラミングわかりませんけど、還暦超えてからスマホを扱いだし、LINEやInstagram楽しんでるようです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away