Python datetime・pytzでタイムゾーン操作完全ガイド【設定・取得・変換・削除】

Pythonでタイムゾーンを扱う方法を、標準ライブラリのdatetimeモジュールとpytzライブラリを使用して詳しく解説します。タイムゾーンの設定、取得、変換、削除の全操作を学びましょう。

タイムゾーンの基本概念

from datetime import datetime, timezone, timedelta
import pytz

# UTC(協定世界時)
utc_now = datetime.now(timezone.utc)
print(f"UTC: {utc_now}")

# ローカルタイムゾーン
local_now = datetime.now()
print(f"ローカル: {local_now}")

# pytzによる日本標準時
jst = pytz.timezone('Asia/Tokyo')
jst_now = datetime.now(jst)
print(f"JST: {jst_now}")

タイムゾーンの設定

標準ライブラリでのタイムゾーン設定

from datetime import datetime, timezone, timedelta

# UTC設定
dt_utc = datetime(2024, 1, 15, 14, 30, 25, tzinfo=timezone.utc)
print(f"UTC: {dt_utc}")

# 固定オフセットのタイムゾーン設定
jst_offset = timezone(timedelta(hours=9))
dt_jst = datetime(2024, 1, 15, 23, 30, 25, tzinfo=jst_offset)
print(f"JST: {dt_jst}")

# ナイーブ(タイムゾーン情報なし)からアウェア(情報あり)に変換
naive_dt = datetime(2024, 1, 15, 14, 30, 25)
aware_dt = naive_dt.replace(tzinfo=timezone.utc)
print(f"変換後: {aware_dt}")

pytzでのタイムゾーン設定

import pytz
from datetime import datetime

# 主要なタイムゾーンの設定
utc = pytz.UTC
jst = pytz.timezone('Asia/Tokyo')
est = pytz.timezone('US/Eastern')
pst = pytz.timezone('US/Pacific')

# localizeメソッドでタイムゾーンを設定
naive_dt = datetime(2024, 1, 15, 14, 30, 25)
jst_dt = jst.localize(naive_dt)
print(f"JST設定: {jst_dt}")

# 夏時間の考慮
est_dt = est.localize(datetime(2024, 7, 15, 14, 30, 25))
print(f"EST(夏時間): {est_dt}")

タイムゾーン情報の取得

現在のタイムゾーン情報を取得

from datetime import datetime
import pytz

# datetimeオブジェクトからタイムゾーン情報を取得
jst = pytz.timezone('Asia/Tokyo')
dt = jst.localize(datetime(2024, 1, 15, 14, 30, 25))

print(f"タイムゾーン名: {dt.tzinfo}")           # Asia/Tokyo
print(f"タイムゾーン略称: {dt.tzname()}")       # JST
print(f"UTCオフセット: {dt.utcoffset()}")       # 9:00:00
print(f"夏時間: {dt.dst()}")                   # 0:00:00

利用可能なタイムゾーンの一覧

import pytz

# すべてのタイムゾーンの一覧(一部表示)
all_timezones = pytz.all_timezones
print(f"総タイムゾーン数: {len(all_timezones)}")

# 一般的なタイムゾーンの一覧
common_timezones = pytz.common_timezones
print("\n一般的なタイムゾーン(アジア):")
asia_timezones = [tz for tz in common_timezones if 'Asia' in tz]
for tz in asia_timezones[:5]:
    print(f"  {tz}")

国別タイムゾーンの取得

import pytz

# 特定の国のタイムゾーン
jp_timezones = pytz.country_timezones['JP']
us_timezones = pytz.country_timezones['US']

print(f"日本のタイムゾーン: {jp_timezones}")
print(f"アメリカのタイムゾーン数: {len(us_timezones)}")
print(f"アメリカ主要都市: {us_timezones[:5]}")

タイムゾーンの変換

基本的なタイムゾーン変換

import pytz
from datetime import datetime

# 元の時刻(JST)
jst = pytz.timezone('Asia/Tokyo')
original_dt = jst.localize(datetime(2024, 1, 15, 23, 30, 25))
print(f"元の時刻(JST): {original_dt}")

# 他のタイムゾーンに変換
utc_dt = original_dt.astimezone(pytz.UTC)
est_dt = original_dt.astimezone(pytz.timezone('US/Eastern'))
pst_dt = original_dt.astimezone(pytz.timezone('US/Pacific'))

print(f"UTC: {utc_dt}")
print(f"EST: {est_dt}")
print(f"PST: {pst_dt}")

複数タイムゾーンの一括変換

import pytz
from datetime import datetime

def convert_to_multiple_timezones(dt, timezones):
    """一つの時刻を複数のタイムゾーンに変換"""
    results = {}
    for tz_name in timezones:
        tz = pytz.timezone(tz_name)
        converted = dt.astimezone(tz)
        results[tz_name] = converted
    return results

# 使用例
base_time = pytz.timezone('Asia/Tokyo').localize(
    datetime(2024, 1, 15, 12, 0, 0)
)

target_zones = [
    'UTC',
    'US/Eastern',
    'US/Pacific',
    'Europe/London',
    'Australia/Sydney'
]

conversions = convert_to_multiple_timezones(base_time, target_zones)
print("JST 12:00の世界各地での時刻:")
for tz_name, converted_time in conversions.items():
    print(f"  {tz_name}: {converted_time.strftime('%H:%M (%Z)')}")

夏時間を考慮した変換

import pytz
from datetime import datetime

def safe_timezone_conversion(dt, target_tz):
    """夏時間を考慮した安全なタイムゾーン変換"""
    try:
        if isinstance(target_tz, str):
            target_tz = pytz.timezone(target_tz)
        
        converted = dt.astimezone(target_tz)
        
        # 夏時間情報の表示
        dst_info = "(夏時間)" if converted.dst() else "(標準時間)"
        return converted, dst_info
    except Exception as e:
        return None, f"エラー: {e}"

# 夏時間期間での変換テスト
summer_jst = pytz.timezone('Asia/Tokyo').localize(
    datetime(2024, 7, 15, 12, 0, 0)
)

est_result, est_info = safe_timezone_conversion(summer_jst, 'US/Eastern')
print(f"夏時間期間 JST → EST: {est_result} {est_info}")

タイムゾーン情報の削除

アウェアからナイーブへの変換

from datetime import datetime
import pytz

# タイムゾーン情報付きの時刻
jst = pytz.timezone('Asia/Tokyo')
aware_dt = jst.localize(datetime(2024, 1, 15, 14, 30, 25))
print(f"アウェア: {aware_dt}")
print(f"タイムゾーン情報: {aware_dt.tzinfo}")

# タイムゾーン情報を削除(ナイーブに変換)
naive_dt = aware_dt.replace(tzinfo=None)
print(f"ナイーブ: {naive_dt}")
print(f"タイムゾーン情報: {naive_dt.tzinfo}")

UTCに変換してからタイムゾーン削除

import pytz
from datetime import datetime

def remove_timezone_as_utc(aware_dt):
    """UTCに変換してからタイムゾーン情報を削除"""
    utc_dt = aware_dt.astimezone(pytz.UTC)
    naive_utc = utc_dt.replace(tzinfo=None)
    return naive_utc

# 使用例
jst_dt = pytz.timezone('Asia/Tokyo').localize(
    datetime(2024, 1, 15, 23, 30, 25)
)

naive_utc = remove_timezone_as_utc(jst_dt)
print(f"元の時刻(JST): {jst_dt}")
print(f"UTC変換後ナイーブ: {naive_utc}")

実用的な応用例

世界時計アプリケーション

import pytz
from datetime import datetime

class WorldClock:
    def __init__(self):
        self.timezones = {
            '東京': 'Asia/Tokyo',
            'ニューヨーク': 'US/Eastern',
            'ロンドン': 'Europe/London',
            'シドニー': 'Australia/Sydney',
            'ロサンゼルス': 'US/Pacific'
        }
    
    def show_current_times(self):
        """現在時刻を各タイムゾーンで表示"""
        utc_now = datetime.now(pytz.UTC)
        
        print("=== 世界時計 ===")
        for city, tz_name in self.timezones.items():
            tz = pytz.timezone(tz_name)
            local_time = utc_now.astimezone(tz)
            print(f"{city:8}: {local_time.strftime('%Y-%m-%d %H:%M:%S %Z')}")

# 使用例
world_clock = WorldClock()
world_clock.show_current_times()

会議スケジューラー

import pytz
from datetime import datetime

class MeetingScheduler:
    def __init__(self):
        self.participants = {
            'Tokyo': 'Asia/Tokyo',
            'New York': 'US/Eastern',
            'London': 'Europe/London'
        }
    
    def schedule_meeting(self, base_city, base_time_str):
        """指定都市の時刻で会議をスケジュール"""
        # 基準時刻の解析
        base_tz = pytz.timezone(self.participants[base_city])
        base_dt = datetime.strptime(base_time_str, '%Y-%m-%d %H:%M')
        base_aware = base_tz.localize(base_dt)
        
        print(f"=== 会議スケジュール({base_city}基準)===")
        
        for city, tz_name in self.participants.items():
            tz = pytz.timezone(tz_name)
            local_time = base_aware.astimezone(tz)
            
            # 営業時間チェック
            hour = local_time.hour
            if 9 <= hour <= 17:
                status = "✅ 営業時間内"
            else:
                status = "❌ 営業時間外"
            
            print(f"{city:10}: {local_time.strftime('%m/%d %H:%M')} {status}")

# 使用例
scheduler = MeetingScheduler()
scheduler.schedule_meeting('Tokyo', '2024-01-15 14:00')

ログファイルのタイムゾーン変換

import pytz
import re
from datetime import datetime

def convert_log_timestamps(log_content, source_tz, target_tz):
    """ログファイルのタイムスタンプを別のタイムゾーンに変換"""
    source = pytz.timezone(source_tz)
    target = pytz.timezone(target_tz)
    
    # タイムスタンプパターン(例:2024-01-15 14:30:25)
    pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})'
    
    def convert_timestamp(match):
        timestamp_str = match.group(1)
        # 元のタイムゾーンでローカライズ
        dt = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S')
        source_dt = source.localize(dt)
        # ターゲットタイムゾーンに変換
        target_dt = source_dt.astimezone(target)
        return target_dt.strftime('%Y-%m-%d %H:%M:%S %Z')
    
    return re.sub(pattern, convert_timestamp, log_content)

# 使用例
sample_log = """
2024-01-15 14:30:25 INFO: Application started
2024-01-15 14:31:00 ERROR: Connection failed
2024-01-15 14:31:15 INFO: Retry successful
"""

converted_log = convert_log_timestamps(sample_log, 'UTC', 'Asia/Tokyo')
print("変換後のログ:")
print(converted_log)

エラーハンドリングとベストプラクティス

曖昧な時刻の処理

import pytz
from datetime import datetime

def safe_localize(tz, dt, is_dst=None):
    """夏時間切り替え時の曖昧な時刻を安全に処理"""
    try:
        return tz.localize(dt, is_dst=is_dst)
    except pytz.AmbiguousTimeError:
        print(f"曖昧な時刻: {dt}")
        # デフォルトで標準時間を選択
        return tz.localize(dt, is_dst=False)
    except pytz.NonExistentTimeError:
        print(f"存在しない時刻: {dt}")
        return None

# 夏時間切り替え時のテスト
eastern = pytz.timezone('US/Eastern')
# 2024年の夏時間終了時(曖昧な時刻)
ambiguous_time = datetime(2024, 11, 3, 1, 30)
result = safe_localize(eastern, ambiguous_time)
print(f"処理結果: {result}")

タイムゾーン変換のユーティリティクラス

import pytz
from datetime import datetime

class TimezoneConverter:
    def __init__(self):
        self.cache = {}
    
    def get_timezone(self, tz_name):
        """タイムゾーンオブジェクトのキャッシュ取得"""
        if tz_name not in self.cache:
            self.cache[tz_name] = pytz.timezone(tz_name)
        return self.cache[tz_name]
    
    def convert(self, dt, from_tz, to_tz):
        """安全なタイムゾーン変換"""
        try:
            # 文字列の場合はタイムゾーンオブジェクトに変換
            if isinstance(from_tz, str):
                from_tz = self.get_timezone(from_tz)
            if isinstance(to_tz, str):
                to_tz = self.get_timezone(to_tz)
            
            # ナイーブな場合はfrom_tzでローカライズ
            if dt.tzinfo is None:
                dt = from_tz.localize(dt)
            
            # ターゲットタイムゾーンに変換
            return dt.astimezone(to_tz)
        
        except Exception as e:
            print(f"変換エラー: {e}")
            return None

# 使用例
converter = TimezoneConverter()
naive_dt = datetime(2024, 1, 15, 14, 30, 25)
result = converter.convert(naive_dt, 'Asia/Tokyo', 'US/Eastern')
print(f"変換結果: {result}")

まとめ

  • 設定方法
    • 標準ライブラリ:timezone(), replace(tzinfo=...)
    • pytz:localize(), timezone()
  • 変換方法astimezone()でタイムゾーン変換
  • 削除方法replace(tzinfo=None)でナイーブに変換
  • 実用例:世界時計、会議スケジューラー、ログ変換
  • 注意点:夏時間の考慮、曖昧な時刻の処理

適切なタイムゾーン処理により、国際的なアプリケーション開発が効率的に行えます。

らくらくPython塾 – 読むだけでマスター

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座