[Python3] struct_timeからdatetimeに変換する方法（タイムゾーン付き）

# はじめに

タイムゾーンを考慮しつつ [time.struct_time](https://docs.python.org/ja/3/library/time.html#time.struct_time) から [datetime.datetime](https://docs.python.org/ja/3/library/datetime.html#datetime.datetime) に変換する方法を片っ端から挙げていきます。
Python 3 向けです。


# タイムゾーンについて

各種例では `Asia/Tokyo (JST)` で変換していますが、ローカルタイムに依存しない変換なのでタイムゾーンを他の地域に変えても動きます。


# struct_time から datetime(naive) に変換

タイムゾーン情報を持たない（naiveな）datetime に変換する方法です。

`datetime(*struct_time[:6])`

```python
from datetime import datetime

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
dt = datetime(*struct_time[:6])
# -------------------------------

print(dt)
# 2019-07-03 07:32:12
```


# struct_time(UTC) から datetime(JST) に変換

## UTC > JST (datetimeのみ)

datetime モジュールのみを使って UTC の struct_time から JST の datetime に変換する方法です。

`datetime(*struct_time[:6], tzinfo=timezone.utc).astimezone(timezone())`

```python
from datetime import datetime, timedelta, timezone

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
tz = timezone(timedelta(hours=+9), 'Asia/Tokyo')
d_jst = datetime(*struct_time[:6], tzinfo=timezone.utc).astimezone(tz)
# -------------------------------

print(d_jst)
# 2019-07-03 16:32:12+09:00
```

## UTC > JST (pytz)

datetime モジュールと pytz ライブラリを使って UTC の struct_time から JST の datetime に変換する方法です。

`datetime(*struct_time[:6], tzinfo=pytz.utc).astimezone(pytz.timezone())`

```python
from datetime import datetime
import pytz

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
tz = pytz.timezone('Asia/Tokyo')
d_jst = datetime(*struct_time[:6], tzinfo=pytz.utc).astimezone(tz)
# -------------------------------

print(d_jst)
# 2019-07-03 16:32:12+09:00
```

## UTC > JST (calendar.timegm)

datetime モジュールと calendar モジュールを使って UTC の struct_time から JST の datetime に変換する方法です。

`datetime.fromtimestamp(timegm(struct_time), tz=timezone())`

```python
from datetime import datetime, timedelta, timezone
from calendar import timegm

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
tz = timezone(timedelta(hours=+9), 'Asia/Tokyo')
d_jst = datetime.fromtimestamp(timegm(struct_time), tz=tz)
# -------------------------------

print(d_jst)
# 2019-07-03 16:32:12+09:00
```

## UTC > JST (calendar.timegm + pytz)

datetime モジュールと calendar モジュールと pytz ライブラリを使って UTC の struct_time から JST の datetime に変換する方法です。

`datetime.fromtimestamp(timegm(struct_time), tz=pytz.timezone())`

```python
from datetime import datetime
from calendar import timegm
import pytz

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
tz = pytz.timezone('Asia/Tokyo')
d_jst = datetime.fromtimestamp(timegm(struct_time), tz=tz)
# -------------------------------

print(d_jst)
# 2019-07-03 16:32:12+09:00
```


# struct_time(JST) から datetime(JST) に変換

## JST > JST (datetimeのみ)

datetime モジュールのみを使って JST の struct_time から JST の datetime に変換する方法です。

`datetime(*struct_time[:6], tzinfo=timezone())`

```python
from datetime import datetime, timedelta, timezone

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
tz = timezone(timedelta(hours=+9), 'Asia/Tokyo')
d_jst = datetime(*struct_time[:6], tzinfo=tz)
# -------------------------------

print(d_jst)
# 2019-07-03 07:32:12+09:00
```

## JST > JST (pytz)

datetime モジュールと pytz ライブラリを使って JST の struct_time から JST の datetime に変換する方法です。

`pytz.timezone().localize(datetime(*struct_time[:6]))`

```python
from datetime import datetime
import pytz

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
tz = pytz.timezone('Asia/Tokyo')
d_jst = tz.localize(datetime(*struct_time[:6]))
# -------------------------------

print(d_jst)
# 2019-07-03 07:32:12+09:00
```


# struct_time(JST) から datetime(UTC) に変換

## JST > UTC (datetimeのみ)

datetime モジュールのみを使って JST の struct_time から UTC の datetime に変換する方法です。

`datetime(*struct_time[:6], tzinfo=timezone()).astimezone(timezone.utc)`

```python
from datetime import datetime, timedelta, timezone

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
tz = timezone(timedelta(hours=+9), 'Asia/Tokyo')
d_utc = datetime(*struct_time[:6], tzinfo=tz).astimezone(timezone.utc)
# -------------------------------

print(d_utc)
# 2019-07-02 22:32:12+00:00
```

## JST > UTC (pytz)

datetime モジュールと pytz ライブラリを使って JST の struct_time から UTC の datetime に変換する方法です。

`pytz.timezone().localize(datetime(*struct_time[:6])).astimezone(pytz.utc)`

```python
from datetime import datetime
import pytz

struct_time = datetime.strptime('2019-07-03 07:32:12', '%Y-%m-%d %H:%M:%S').timetuple()

# --- struct_time -> datetime ---
tz = pytz.timezone('Asia/Tokyo')
d_utc = tz.localize(datetime(*struct_time[:6])).astimezone(pytz.utc)
# -------------------------------

print(d_utc)
# 2019-07-02 22:32:12+00:00
```