LoginSignup
4
2

More than 3 years have passed since last update.

datetimeで嵌るパターン in Python3

Last updated at Posted at 2019-09-16

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楽しんでるようです。

4
2
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
4
2