Python で文字列を日時データに変換,時分秒の切り捨て,日時の比較,日時データの数え上げ
1. エグゼクティブサマリー
本記事では,Python を用いて文字列を日時データ(datetime.datetime 型)に変換する方法,時分秒の切り捨て,日時の比較,および日時データの数え上げについて解説する。
具体的には,以下の処理を扱う。
- 文字列を datetime.datetime 型に変換する方法(
strptimeメソッドの使用) - 秒,分,時の切り捨て(その日の 0時 0分の取得,0時 0分からの経過秒数の算出,分の始めからの経過秒数の算出)
- 日時の引き算(指定した秒数だけ前の日時の算出,2つの日時の差を日数で求める方法)
- 日時の比較(基準日時との比較による True/False 判定)
- 日時の数え上げ(pandas の value_counts を使った一定秒数ごとの数え上げ,日付による行の選択)
- datetime.datetime 型を文字列に変換する方法(
strftimeメソッドの使用)
タイムゾーン情報(+09:00 等)を含む日時文字列の扱いを前提とし,datetime モジュールの strptime/strftime による変換,timestamp() による数値演算,timedelta による日時計算,および pandas DataFrame との連携を実例とともに示す。
2. 前準備(必要ソフトウェアの入手)
ここでは、最低限の事前準備について説明する。機械学習や深層学習を行う場合は、NVIDIA CUDA、Visual Studio、Cursorなどを追加でインストールすると便利である。これらについては別ページ https://www.kkaneko.jp/cc/dev/aiassist.htmlで詳しく解説しているので、必要に応じて参照してください。
Python 3.12 のインストール(Windows 上) [クリックして展開]
以下のいずれかの方法で Python 3.12 をインストールする。Python がインストール済みの場合、この手順は不要である。
方法1:winget によるインストール
管理者権限のコマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。
winget install --scope machine --id Python.Python.3.12 -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_pip=1 Include_test=0 Include_launcher=1 InstallLauncherAllUsers=1"
--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動すると PATH が自動的に設定される。
方法2:インストーラーによるインストール
- Python 公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンから Windows 用インストーラーをダウンロードする。
- ダウンロードしたインストーラーを実行する。
- 初期画面の下部に表示される「Add python.exe to PATH」に必ずチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから
pythonコマンドを実行できない。 - 「Install Python 3.xx for all users」にチェックを入れ、「Install」をクリックする。
インストールの確認
コマンドプロンプトで以下を実行する。
python --version
バージョン番号(例:Python 3.12.x)が表示されればインストール成功である。「'python' は、内部コマンドまたは外部コマンドとして認識されていません。」と表示される場合は、インストールが正常に完了していない。
AIエディタ Windsurf のインストール(Windows 上) [クリックして展開]
Pythonプログラムの編集・実行には、AIエディタの利用を推奨する。ここでは、Windsurfのインストールを説明する。Windsurf がインストール済みの場合、この手順は不要である。
管理者権限のコマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには、Windows キーまたはスタートメニューから「cmd」と入力し、表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。
winget install --scope machine --id Codeium.Windsurf -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --custom "/SP- /SUPPRESSMSGBOXES /NORESTART /CLOSEAPPLICATIONS /DIR=""C:\Program Files\Windsurf"" /MERGETASKS=!runcode,addtopath,associatewithfiles,!desktopicon"
powershell -Command "$env:Path=[System.Environment]::GetEnvironmentVariable('Path','Machine')+';'+[System.Environment]::GetEnvironmentVariable('Path','User'); windsurf --install-extension MS-CEINTL.vscode-language-pack-ja --force; windsurf --install-extension ms-python.python --force; windsurf --install-extension Codeium.windsurfPyright --force"
--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動すると PATH が自動的に設定される。
【関連する外部ページ】
Windsurf の公式ページ: https://windsurf.com/
必要なライブラリのインストール [クリックして展開]
管理者権限のコマンドプロンプトで以下を実行する。管理者権限のコマンドプロンプトを起動するには,Windows キーまたはスタートメニューから「cmd」と入力し,表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する。
pip install -U pandas
本記事のプログラムでは,標準ライブラリの datetime に加え,外部ライブラリの pandas を使用する。datetime は Python に標準で含まれるため,別途インストールは不要である。
3. 実行のための準備とその確認手順(Windows 前提)
3.1 プログラムファイルの準備
第5章に掲載するソースコードをテキストエディタ(メモ帳,Windsurf 等)に貼り付け,main.py として保存する(文字コード:UTF-8)。本記事には複数の独立したコードブロックが含まれる。各コードブロックは単独で実行可能であるため,確認したいコードブロックの内容を main.py に貼り付けて保存し,順に実行する。
3.2 実行コマンド
コマンドプロンプトでファイルの保存先ディレクトリに移動し,以下を実行する。
cd ファイルの保存先ディレクトリ
python main.py
3.3 動作確認チェックリスト
| 確認項目 | 期待される結果 |
|---|---|
| 文字列を datetime.datetime 型に変換するコードの実行 | 変換後の日時 2020-06-30 13:00:00+09:00 とタイムゾーン情報 UTC+09:00 が表示される |
| その日の 0時 0分を取得するコードの実行 | 2020-06-30 00:00:00+09:00 とタイムゾーン情報が表示される |
| 0時 0分からの経過秒数を求めるコードの実行 | 41904.0 が表示される |
| 分の始めからの経過秒数を求めるコードの実行 | 日時と経過秒数 24.0 が表示される |
| 60秒前の日時を求めるコードの実行 | 元の日時と60秒前の日時が表示される |
| 2つの日時の差を日数で求めるコードの実行 | 9 が表示される |
| 日時の比較コードの実行 | basetime 以降の日時に対して True,以前の日時に対して False が表示される |
| 300秒ごとの数え上げコードの実行 | 300秒区間ごとの件数が value_counts の結果として表示される |
| 日付による行選択コードの実行 | 指定した日付と同じ日のデータのみが選択・表示される |
| datetime.datetime 型を文字列に変換するコードの実行 | 2020/06/30 13:00:00 および 2020年06月30日 が表示される |
4. 概要・使い方・実行上の注意
4.1 文字列を datetime.datetime 型に変換
次のような日時を表す文字列があるとする。
"2017-7-1 11:38:24"
文字列を datetime.datetime 型に変換するには,datetime.strptime メソッドを使用する。書式文字列 %Y-%m-%d %H:%M:%S %z を指定することで,年・月・日・時・分・秒・タイムゾーンを含む文字列を解析できる。
4.2 秒,分,時の切り捨て
その日の 0時 0分の取得は,datetime.datetime 型の年・月・日のみを使って新たな datetime オブジェクトを生成することで実現する。結果は datetime.datetime 型で得る。
その日の 0時 0分から,何秒経過したかは,timestamp() メソッドで Unix タイムスタンプに変換し,その差を算出することで求める。
「分の始め」から何秒経過したかは,秒以下を切り捨てた datetime オブジェクトを生成し,元の日時との timestamp() の差を求めることで算出する。
4.3 日時の引き算
ある日時の 60 秒前を求めるには,timedelta(seconds=delta) を日時から減算する。
2つの日時の差を日数で求めるには,datetime オブジェクト同士の減算結果(timedelta 型)の days 属性を参照する。
実行結果として 9 が表示される。
4.4 日時の比較
グローバル変数 basetime で設定された日時以降なら True を返す。datetime オブジェクト同士は比較演算子(>,<,== 等)で直接比較できる。
4.5 日時の数え上げ
次のようなデータがあるとする。日時を 300 秒ごとに区切って value_counts を使って数え上げを行う。経過秒数を 300 で整数除算し,再び 300 を乗じることで,300秒単位の区間に丸めている。
"2020-07-11 0:0:0" と同じ日のデータだけを選択するには,compare_by_date 関数を使用する。この関数は,指定した基準日と同じ日付(0時 0分の比較)かどうかを判定するラムダ関数を返す。
DataFrame に対して日付による選択を行う場合は,map メソッドで compare_by_date を各行に適用し,条件に合致する行を抽出する。
4.6 datetime.datetime 型を文字列に変換
datetime.datetime 型のデータを,指定した書式の文字列に変換するには strftime メソッドを使用する。書式文字列を変更することで,さまざまな形式の文字列を出力できる。
実行結果として 2020/06/30 13:00:00 および 2020年06月30日 が表示される。
5. ソースコード
5.1 文字列を datetime.datetime 型に変換
文字列を datetime.datetime 型に変換
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
x = to_datetime("2020-06-30 13:00:00 +09:00")
print(x)
print(x.tzinfo)
5.2 秒,分,時の切り捨て
その日の 0時 0分の取得。結果は datetime.datetime 型で得る
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
# その日の 0時 0分。パラメータは datetime.datetime 型
def first_of_day(x):
return dt(x.year, x.month, x.day, tzinfo=x.tzinfo)
x = to_datetime("2020-06-30 13:00:00 +09:00")
print(first_of_day(x))
print(first_of_day(x).tzinfo)
その日の 0時 0分から,何秒経過したかを表示
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
# その日の 0時 0分。パラメータは datetime.datetime 型
def first_of_day(x):
return dt(x.year, x.month, x.day, tzinfo=x.tzinfo)
# その日の 0時 0分から,何秒経過したか
def elapsed(x):
return x.timestamp() - first_of_day(x).timestamp()
x = to_datetime("2020-7-1 11:38:24 +09:00")
# 41904.0 が表示される
print(elapsed(x))
「分の始め」から何秒経過したかを表示
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
# 秒以下を切り捨て。パラメータは datetime.datetime 型
def first_of_minute(x):
return dt(x.year, x.month, x.day, x.hour, x.minute, tzinfo=x.tzinfo)
x = to_datetime("2020-7-1 11:38:24 +09:00")
print(x)
print(x.timestamp() - first_of_minute(x).timestamp())
5.3 日時の引き算
ある日時の 60 秒前
from datetime import datetime as dt
from datetime import timedelta
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
# 指定した秒数だけ前の日時を返す
def past_time(x, delta):
return x - timedelta(seconds=delta)
x = to_datetime("2020-7-1 11:38:24 +09:00")
print(x)
print(past_time(x, 60))
2つの日時の差を日数で求める
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
# 2つの日時の差を日数で返す
def days_between(a, b):
return (a - b).days
x = to_datetime("2020-7-10 11:38:24 +09:00")
y = to_datetime("2020-7-1 11:38:24 +09:00")
print(days_between(x, y))
5.4 日時の比較
グローバル変数 basetime で設定された日時以降なら True
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
basetime = to_datetime("2020-06-30 09:00:00 +09:00")
def time_selection(x):
return x > basetime
x = to_datetime("2020-7-1 11:38:24 +09:00")
print(x)
print(time_selection(x))
y = to_datetime("2020-6-29 11:38:24 +09:00")
print(y)
print(time_selection(y))
5.5 日時の数え上げ
日時を 300 秒ごとに区切って value_counts を使って数え上げを行う
import pandas as pd
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
m1 = pd.DataFrame([
[1, "2020-7-1 11:38:00 +09:00"],
[2, "2020-7-1 11:38:00 +09:00"],
[4, "2020-7-1 11:39:00 +09:00"],
[5, "2020-7-1 11:40:00 +09:00"],
[6, "2020-7-1 11:40:00 +09:00"],
[7, "2020-7-1 11:40:00 +09:00"]
],
columns=['id', 'datetime'])
# その日の 0時 0分。パラメータは datetime.datetime 型
def first_of_day(x):
return dt(x.year, x.month, x.day, tzinfo=x.tzinfo)
# その日の 0時 0分から,何秒経過したか
def elapsed(x):
return x.timestamp() - first_of_day(x).timestamp()
x = (m1.datetime.map(to_datetime).map(elapsed) // 300) * 300
print(x.value_counts(sort=True, ascending=True))
"2020-07-11 0:0:0" と同じ日のデータだけを選択する
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
# その日の 0時 0分。パラメータは datetime.datetime 型
def first_of_day(x):
return dt(x.year, x.month, x.day, tzinfo=x.tzinfo)
def compare_by_date(base):
return lambda x: first_of_day(to_datetime(x)) == first_of_day(to_datetime(base))
print(compare_by_date("2020-07-11 0:0:0 +09:00")("2020-07-11 10:0:0 +09:00"))
print(compare_by_date("2020-07-11 0:0:0 +09:00")("2020-07-12 10:0:0 +09:00"))
DataFrame に対して日付による選択を行う
import pandas as pd
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
# その日の 0時 0分。パラメータは datetime.datetime 型
def first_of_day(x):
return dt(x.year, x.month, x.day, tzinfo=x.tzinfo)
def compare_by_date(base):
return lambda x: first_of_day(to_datetime(x)) == first_of_day(to_datetime(base))
m2 = pd.DataFrame([
[1, "2020-7-1 11:38:00 +09:00"],
[2, "2020-7-1 11:38:00 +09:00"],
[4, "2020-7-1 11:39:00 +09:00"],
[5, "2020-7-1 11:40:00 +09:00"],
[6, "2020-7-2 3:10:00 +09:00"],
[7, "2020-7-2 3:10:00 +09:00"]
],
columns=['id', 'datetime'])
print('----')
print(m2[m2.datetime.map(compare_by_date("2020-07-1 0:0:0 +09:00"))])
print('----')
print(m2[m2.datetime.map(compare_by_date("2020-07-2 0:0:0 +09:00"))])
5.6 datetime.datetime 型を文字列に変換
datetime.datetime 型を任意の書式で文字列に変換する
from datetime import datetime as dt
# 文字列を datetime.datetime 型に変換
def to_datetime(x):
return dt.strptime(x, "%Y-%m-%d %H:%M:%S %z")
# datetime.datetime 型を文字列に変換
def to_string(x, fmt="%Y/%m/%d %H:%M:%S"):
return x.strftime(fmt)
x = to_datetime("2020-06-30 13:00:00 +09:00")
print(to_string(x))
print(to_string(x, "%Y年%m月%d日"))
6. まとめ
strptime による文字列から datetime.datetime 型への変換
datetime.strptime メソッドに書式文字列 %Y-%m-%d %H:%M:%S %z を指定することで,タイムゾーン情報を含む日時文字列を datetime.datetime 型に変換できる。
時分秒の切り捨てによる日時の丸め
datetime.datetime 型の年・月・日(および必要に応じて時・分)のみを使って新たな datetime オブジェクトを生成することで,その日の 0時 0分や分の始めの時刻を取得できる。timestamp() の差を求めることで経過秒数も算出できる。
timedelta を用いた日時の引き算
timedelta(seconds=delta) を日時から減算することで,指定した秒数だけ前の日時を求められる。また,datetime オブジェクト同士の減算結果(timedelta 型)の days 属性を参照することで,2つの日時の差を日数で求められる。
datetime オブジェクト同士の比較
datetime オブジェクト同士は比較演算子で直接比較できる。グローバル変数に基準日時を設定し,対象の日時が基準以降かどうかを True/False で判定する方法を示した。
pandas の value_counts を使った日時の数え上げ
経過秒数を一定の秒数(300秒)で整数除算し再び乗じることで,日時を一定区間に丸めて数え上げを行える。pandas DataFrame の map メソッドと value_counts を組み合わせることで,日時データの集計が可能である。