Pythonで秒数と分・時間・日数を相互に変換

Modified: | Tags: Python, 日時処理

Pythonで、秒数と分・時間・日数を相互に変換するには、datetimeモジュールのtimedelta型を利用する。

datetimeモジュールの基本的な内容については以下の記事を参照。

本記事のサンプルコードでは、以下のようにdatetimeモジュールをインポートしている。

import datetime

datetime.timedeltaの基本的な使い方

コンストラクタtimedelta()で生成

timedeltaオブジェクトはコンストラクタに日数や時間、秒数などを指定して生成する。

指定できる引数はweeks, days, hours, minutes, seconds, milliseconds(ミリ秒), microseconds(マイクロ秒)。省略すると0となる。月と年は日数が固定ではないので指定できない。

td = datetime.timedelta(weeks=1, days=1, hours=1, minutes=1,
                        seconds=1, milliseconds=1, microseconds=1)
print(td)
# 8 days, 1:01:01.001001

print(type(td))
# <class 'datetime.timedelta'>

それぞれの引数は浮動小数点数floatやマイナスの値でもよい。hours24以上の値を指定したり、minutesseconds60以上の値を指定しても正しく換算される。

以下の例では0.5日(=12時間)と-6時間と120分(=2時間)が合計されて8時間という結果になっている。

print(datetime.timedelta(days=0.5, hours=-6, minutes=120))
# 8:00:00

なお、timedeltaオブジェクトはdatetimeオブジェクトやdateオブジェクトの引き算でも生成される。

days, seconds, microseconds属性

timedeltaオブジェクトが内部に保持しているのは日数、秒数、マイクロ秒数のみ。それぞれdays, seconds, microseconds属性でアクセスできる。すべて整数int

td = datetime.timedelta(weeks=1, days=1, hours=1, minutes=1,
                        seconds=1, milliseconds=1, microseconds=1)
print(td)
# 8 days, 1:01:01.001001

print(td.days)
print(type(td.days))
# 8
# <class 'int'>

print(td.seconds)
print(type(td.seconds))
# 3661
# <class 'int'>

print(td.microseconds)
print(type(td.microseconds))
# 1001
# <class 'int'>

秒数を分・時間などに変換する方法については後述。

total_seconds()メソッド

total_seconds()メソッドはトータル時間を秒数で返す。返り値は浮動小数点数float

td = datetime.timedelta(weeks=1, days=1, hours=1, minutes=1,
                        seconds=1, milliseconds=1, microseconds=1)
print(td)
# 8 days, 1:01:01.001001

print(td.total_seconds())
# 694861.001001

print(type(td.total_seconds()))
# <class 'float'>

文字列に変換

これまでの例にもあるように、timedeltaオブジェクトをprint()で出力すると8 days, 1:01:01.001001のように日数と時間・分・秒・マイクロ秒が表示される。timedeltaオブジェクトをstr()で文字列に変換すると、同様の文字列が得られる。

td = datetime.timedelta(weeks=1, days=1, hours=1, minutes=1,
                        seconds=1, milliseconds=1, microseconds=1)
print(td)
# 8 days, 1:01:01.001001

s = str(td)
print(s)
# 8 days, 1:01:01.001001

print(type(s))
# <class 'str'>

分・時間・日数などを秒数に変換

分・時間・日数などから秒数を算出するには、コンストラクタでtimedeltaオブジェクトを生成してからtotal_seconds()メソッドを使うのが簡単。上述のようにfloatが返される。

td = datetime.timedelta(days=1, hours=1, milliseconds=100)
sec = td.total_seconds()
print(sec)
# 90000.1

print(type(sec))
# <class 'float'>

続けて書いてもよい。

sec = datetime.timedelta(days=1, hours=1, milliseconds=100).total_seconds()
print(sec)
# 90000.1

秒数を分・時間・日数などに変換

秒数を分・時間・日数などを使って表したい場合も、一旦timedeltaオブジェクトに変換すると簡単。

timedeltaのコンストラクタの引数secondsに秒数を指定する。浮動小数点数floatでも指定可能。print()での出力結果を文字列として取得するだけであれば、str()で変換すればよい。

td = datetime.timedelta(seconds=123456.789)
print(td)
# 1 day, 10:17:36.789000

s = str(td)
print(s)
# 1 day, 10:17:36.789000

print(type(s))
# <class 'str'>

上述のように、timedeltaオブジェクトの属性として得られるのはdays, seconds, microsecondsのみ。

print(td.days)
# 1

print(td.seconds)
# 37056

print(td.microseconds)
# 789000

秒数を分・時間および残りの秒数に変換するには、以下のような関数が考えられる。

def get_h_m_s(sec):
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    return h, m, s

timedelta型の__str__()を参考にした。

divmod()については以下の記事を参照。

返り値はタプル。アンパックしてそれぞれの変数に格納できる。

print(get_h_m_s(td.seconds))
# (10, 17, 36)

print(type(get_h_m_s(td.seconds)))
# <class 'tuple'>

h, m, s = get_h_m_s(td.seconds)
print(h)
# 10

print(m)
# 17

print(s)
# 36

秒数を日・時間・分・秒・マイクロ秒に変換するには、以下のような関数が考えられる。上の関数と同じく、返り値はタプル。

def get_d_h_m_s_us(sec):
    td = datetime.timedelta(seconds=sec)
    m, s = divmod(td.seconds, 60)
    h, m = divmod(m, 60)
    return td.days, h, m, s, td.microseconds

print(get_d_h_m_s_us(123456.789))
# (1, 10, 17, 36, 789000)

print(get_d_h_m_s_us(123.456789))
# (0, 0, 2, 3, 456789)

負の秒数の場合

負の秒数の場合は注意が必要。

トータルの秒数が負のtimedeltaオブジェクトは、以下のように日数daysが負で秒数secondsとマイクロ秒数microsecondsが正になる。

td_m = datetime.timedelta(seconds=-123456.789)
print(td_m)
# -2 days, 13:42:23.211000

print(td_m.days)
# -2

print(td_m.seconds)
# 49343

print(td_m.microseconds)
# 211000

print(td_m.total_seconds())
# -123456.789

上で定義した関数もそれに準じた値を返す。

print(get_d_h_m_s_us(-123456.789))
# (-2, 13, 42, 23, 211000)

絶対値を算出する組み込み関数abs()timedeltaオブジェクトに対しても有効なので、期間(幅)として換算したい場合はabs()を使えばよい。

print(abs(td_m))
# 1 day, 10:17:36.789000

print(get_d_h_m_s_us(abs(-123456.789)))
# (1, 10, 17, 36, 789000)

関連カテゴリー

関連記事