Pytz,一个时区处理大师的 Python 库!

文摘   2024-11-03 07:00   上海  

哈喽,大家好!我是风哥,一个资深Python工程师。今天给大家介绍一个特别实用的Python库——Pytz!写全球化项目的时候,老是被时区问题搞得头大?东八区西六区分不清?夏令时冬令时傻傻分不清楚?别急,今天风哥就教你用Pytz轻松搞定这些烦恼!

安装和基础配置

先把这个神器装上:

1pip install pytz

一般项目里建议这么导入:

1import pytz
2from datetime import datetime, timedelta
3from typing import Optional, Union

时区对象进阶操作

创建时区对象有讲究:

 1# 获取所有时区名称
2available_zones = pytz.all_timezones
3
4# 获取常见时区
5common_zones = pytz.common_timezones
6
7# 通过国家代码获取时区
8country_zones = pytz.country_timezones('CN')  # 中国的时区
9
10# 获取国家信息
11country_info = pytz.country_names['CN']  # 中国的信息

温馨提示:别直接用字符串硬编码时区名,最好通过这些方法动态获取!

高级时区转换

来点进阶操作:

 1class TimezoneConverter:
2    def __init__(self, default_tz: str = 'UTC'):
3        self.default_tz = pytz.timezone(default_tz)
4
5    def convert_time(self, 
6                    dt: datetime, 
7                    target_tz: str,
8                    preserve_timezone: bool = False)
 -> datetime:

9        """智能时区转换器"""
10        try:
11            target_timezone = pytz.timezone(target_tz)
12
13            # 处理naive datetime
14            if dt.tzinfo is None:
15                dt = self.default_tz.localize(dt)
16
17            # 转换时区
18            converted = dt.astimezone(target_timezone)
19
20            # 是否保留时区信息
21            if not preserve_timezone:
22                converted = converted.replace(tzinfo=None)
23
24            return converted
25
26        except pytz.exceptions.UnknownTimeZoneError:
27            raise ValueError(f"未知时区: {target_tz}")

处理时间戳

实际项目中经常要处理时间戳:

 1def timestamp_converter(timestamp: Union[int, float], 
2                       source_tz: str = 'UTC',
3                       target_tz: str = 'Asia/Shanghai')
 -> datetime:

4    """时间戳转换器"""
5    source = pytz.timezone(source_tz)
6    target = pytz.timezone(target_tz)
7
8    # 处理毫秒级时间戳
9    if len(str(int(timestamp))) > 10:
10        timestamp = timestamp / 1000
11
12    dt = datetime.fromtimestamp(timestamp, source)
13    return dt.astimezone(target)

批量时区处理

处理大量数据时的优化方案:

 1from typing import List, Dict
2import pandas as pd
3
4def batch_timezone_convert(timestamps: List[float],
5                         source_tz: str,
6                         target_tz: str)
 -> List[datetime]:

7    """批量时区转换(性能优化版)"""
8    source = pytz.timezone(source_tz)
9    target = pytz.timezone(target_tz)
10
11    # 使用向量化操作提升性能
12    df = pd.DataFrame({'timestamp': timestamps})
13    df['datetime'] = pd.to_datetime(df['timestamp'], unit='s')
14    df['datetime'] = df['datetime'].dt.tz_localize(source)
15    df['datetime'] = df['datetime'].dt.tz_convert(target)
16
17    return df['datetime'].tolist()

处理特殊场景

夏令时和历史时区变更处理:

 1def is_dst_time(dt: datetime, timezone_str: str) -> bool:
2    """检查是否是夏令时"""
3    tz = pytz.timezone(timezone_str)
4    timezone_aware_date = tz.localize(dt, is_dst=None)
5    return timezone_aware_date.dst() != timedelta(0)
6
7def get_timezone_transitions(timezone_str: str, 
8                           year: int)
 -> List[Dict]:

9    """获取时区变更历史"""
10    tz = pytz.timezone(timezone_str)
11    transitions = []
12
13    for dt in tz._utc_transition_times:
14        if dt.year == year:
15            info = tz._transition_info[
16                tz._utc_transition_times.index(dt)
17            ]
18            transitions.append({
19                'time': dt,
20                'offset': info[0],
21                'dst': info[1],
22                'name': info[2]
23            })
24
25    return transitions

温馨提示:处理历史数据时,一定要考虑时区政策变更的影响!

实用工具函数

整几个常用的工具函数:

 1def get_current_timezone() -> str:
2    """获取系统当前时区"""
3    return str(datetime.now(pytz.timezone('localtime')).tzinfo)
4
5def format_timezone_offset(tz_name: str) -> str:
6    """格式化时区偏移量"""
7    tz = pytz.timezone(tz_name)
8    offset = tz.utcoffset(datetime.now())
9    hours = offset.total_seconds() / 3600
10    return f"UTC{'+' if hours >= 0 else ''}{int(hours):02d}:00"
11
12def find_timezone_by_offset(offset_hours: float) -> List[str]:
13    """通过偏移量查找时区"""
14    target_offset = timedelta(hours=offset_hours)
15    matching_zones = []
16
17    for tz_name in pytz.all_timezones:
18        tz = pytz.timezone(tz_name)
19        if tz.utcoffset(datetime.now()) == target_offset:
20            matching_zones.append(tz_name)
21
22    return matching_zones

今天的Python学习之旅就到这里啦!记得动手敲代码,有问题随时在评论区问风哥哦。祝大家学习愉快,收获满满!

py学习基地ai
分享生活百态,情感故事,了解不一样的人生
 最新文章