[Python] 時刻取得まとめ：用途別の最適な方法


## In a nutshell
Pythonでの時刻取得方法を整理し，それぞれの用途や適したシチュエーションを解説した．また，ローカル時刻，エポック秒，タイムゾーン対応，時間計測の方法を比較して，最適なライブラリ選択の指針を表形式で示し，実用的な活用方法を提案した．


## 記事の目的
Python において，現在の時刻を取得する方法はいくつかある．しかし，どのような場合にどれを用いる事が適切であるのかを知らなかったので調べた．それについて，以下に纏めた．


## 想定される読み手
 - Python に関して，初学者である
 - 時刻取得に関して興味がある



## 1. `datetime.datetime.now()`
### 用途・シチュエーション:
- **一般的な日時取得**: 日付や時刻を扱うシンプルな処理に最適．
- **フォーマットの自由度**: `.strftime()` を使ってフォーマットを変更しやすい．
- **ローカル時刻の取得**: `datetime.now()` はデフォルトでシステムのローカルタイムを取得する．

### 注意点:
- タイムゾーン情報は含まれないため，グローバルな処理には `pytz` との併用が必要．

### スクリプト例

```python
from datetime import datetime

# 現在の日時を取得
time_datetime= datetime.now()
print(time_datetime) 

# 2025-03-20 16:25:35.654095
```


## 2. `time.time()`
### 用途・シチュエーション:
- **エポック秒（Unix時間）の取得**: 1970年1月1日からの経過秒数で時刻を扱いたいときに最適．
- **時間差の計測**: 2つの `time.time()` の差を取ることで処理時間を計測できる．

### 注意点:
- 可読性が低いため，直接ユーザー向けに表示する用途には適さない．

### スクリプト例

```python
import time

# 現在の時刻（エポック秒）を取得
time_time = time.time()
print(time_time)  
print(f"{time_time:.3f}")  # 小数点以下3桁まで表示

# 1742455535.6543741
# 1742455535.654
```

## 3. `time.localtime()` + `time.strftime()`
### 用途・シチュエーション:
- **ローカル時刻を文字列として扱う**: `strftime()` によりフォーマットを簡単に変更できる．
- **ログ出力やUI表示**: `YYYY-MM-DD HH:MM:SS` のような形に整えやすい．

### 注意点:
- `datetime` に比べると直感的でない場合がある．

### スクリプト例

```python
import time

# 現在の時刻をフォーマットして表示
local_time = time.localtime()
formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
print(formatted_time)  

# 2025-03-20 16:25:35
```


## 4. `datetime.now(pytz.timezone("Asia/Tokyo"))`
### 用途・シチュエーション:
- **タイムゾーンを明示的に指定する必要がある場合**: タイムゾーンが重要なアプリケーション（例: グローバル対応のWebサービス）．
- **異なるタイムゾーン間での時刻変換**: `pytz.timezone("UTC").localize(dt).astimezone(pytz.timezone("Asia/Tokyo"))` などが可能．

### 注意点:
- `pytz` は標準ライブラリではないため，`pip install pytz` が必要．

### スクリプト例

```python
from datetime import datetime
import pytz

# タイムゾーンを指定して現在時刻を取得
time_pytz = pytz.timezone("Asia/Tokyo")
tokyo_time = datetime.now(time_pytz)
print(tokyo_time)  

# 2025-03-20 16:25:35.943172+09:00
```


## 5. `arrow.now()`
### 用途・シチュエーション:
- **`datetime` より直感的な時刻操作**: `.shift(days=1)` で簡単に1日後の時刻を取得可能．
- **タイムゾーンを簡単に扱える**: `.to('Asia/Tokyo')` で変換できる．
- **WebアプリやAPIでの時刻処理**: ISO 8601 形式 (`YYYY-MM-DDTHH:MM:SS+TZ`) の出力が容易．

### 注意点:
- `arrow` は標準ライブラリではなく，`pip install arrow` が必要．

### スクリプト例

```python
import arrow

# 現在の時刻を取得
time_arrow= arrow.now()
print(time_arrow)  

# 2025-03-20T16:25:36.045942+09:00
```



## 6. `timeit.default_timer()`
### 用途・シチュエーション:
- **コードの実行時間計測**: `start = timeit.default_timer(); do_something(); elapsed = timeit.default_timer() - start`
- **高精度な時間測定**: `time.time()` より精度が高い（環境によって異なる）．

### 注意点:
- `datetime` や `time` とは異なり，時刻取得の用途には適さない．
- `timeit.default_timer()` は Windows では `time.perf_counter()`，Linux/macOS では `time.monotonic()` を内部的に使用する為，環境ごとに挙動が異なることがある．


### スクリプト例

```python
import timeit

# 現在の時刻をエポック秒で取得
timestamp = timeit.default_timer()
print(timestamp)  

# 15251.0218552
```


## 7. `time.perf_counter()`
### 用途・シチュエーション:
- **高精度な時間計測**: `timeit.default_timer()` 同様，処理時間の測定に適している．
- **システムの時計と無関係に動作**: システムの時刻とは無関係に動作する為，プロセスの実行時間の測定等に適しており，精度が高い．

### 注意点:
- 絶対的な時刻を取得するのではなく，相対時間の測定向け．

### スクリプト例

```python
import time

# 高精度な時刻取得
current_time = time.perf_counter()
print(current_time)  


# 15251.0220795
```


## どのライブラリを使うべきか？

- **基本的な日時取得** → `datetime.now()`
- **時刻の計算や変換を楽にしたい** → `arrow`
- **タイムゾーンを考慮したい** → `pytz`
- **処理時間計測** → `timeit.default_timer()` or `time.perf_counter()`
- **UNIXタイムが必要** → `time.time()`


| 用途 | 適したライブラリ |
|------|-----------------|
| 現在の日時を取得 (ローカルタイム) | `datetime.datetime.now()` |
| 現在の時刻をエポック秒で取得 | `time.time()` |
| 時刻を特定のフォーマットで表示 | `time.localtime()` + `time.strftime()` |
| タイムゾーンを考慮した時刻取得 | `datetime.now(pytz.timezone(...))` or `arrow.now()` |
| WebAPIや時刻処理を簡単に扱いたい | `arrow` |
| 時間計測 (コードの実行時間) | `timeit.default_timer()` or `time.perf_counter()` |


## Summary

`datetime.now()` はローカル時刻を取得し，フォーマット変更が容易
`time.time()` はエポック秒の取得や時間差の計測向け
`timeit.default_timer()` や `time.perf_counter()` は高精度な時間計測に適している