如何用datetime和pytz获取'US/Easter'类本地时区名称(禁用tzlocal)
获取本地时区标准标识符(不用tzlocal)
我懂你想要的是像US/Eastern这样的标准时区ID,而不是EDT/EST这类随夏令时切换的缩写,而且还不能用tzlocal模块对吧?你之前试的代码返回缩写是因为reference.LocalTimezone()和tzlocal()本质上都是返回“会动态切换名称的时区对象”,它们的tzname()方法本来就会返回当前时段的缩写,而非时区的标准标识符。
那咱们得换个思路:直接从系统层面获取时区配置,再映射到pytz的标准时区ID。下面分系统给你解决方案:
方案1:Linux/macOS系统
这类系统的时区配置通常存在文件或符号链接里,咱们可以直接读取:
import os import pytz from datetime import datetime def get_local_timezone_id(): # 优先读取/etc/timezone(Debian/Ubuntu系常用) if os.path.exists('/etc/timezone'): with open('/etc/timezone') as f: tz_id = f.read().strip() if tz_id in pytz.all_timezones: return tz_id # 读取/etc/localtime的链接目标(多数Linux和macOS) if os.path.islink('/etc/localtime'): tz_path = os.readlink('/etc/localtime') # 路径一般是/usr/share/zoneinfo/US/Eastern,提取最后两段 tz_id = '/'.join(tz_path.split('/')[-2:]) if tz_id in pytz.all_timezones: return tz_id # 兜底:从环境变量TZ获取 env_tz = os.environ.get('TZ') if env_tz and env_tz in pytz.all_timezones: return env_tz # 实在不行返回UTC return 'UTC' # 使用示例 local_tz_id = get_local_timezone_id() print(f"本地时区ID:{local_tz_id}") # 输出类似US/Eastern local_tz = pytz.timezone(local_tz_id) now = datetime.now(local_tz) print(f"当前时间(带时区):{now}") print(f"时区对象信息:{now.tzinfo}")
方案2:Windows系统
Windows的时区名称和pytz的ID不是直接对应,需要通过注册表读取系统时区,再做映射:
import winreg import pytz from datetime import datetime def get_local_timezone_id(): # 从注册表读取Windows时区标识 try: with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation") as key: win_tz_name, _ = winreg.QueryValueEx(key, "TimeZoneKeyName") except Exception as e: print(f"读取时区失败:{e}") return 'UTC' # Windows时区到pytz ID的映射(可以根据需求补充更多) win_to_pytz_map = { 'Eastern Standard Time': 'US/Eastern', 'Central Standard Time': 'US/Central', 'Mountain Standard Time': 'US/Mountain', 'Pacific Standard Time': 'US/Pacific', 'GMT Standard Time': 'Europe/London', 'China Standard Time': 'Asia/Shanghai', 'Japan Standard Time': 'Asia/Tokyo', } return win_to_pytz_map.get(win_tz_name, 'UTC') # 使用示例 local_tz_id = get_local_timezone_id() print(f"本地时区ID:{local_tz_id}") local_tz = pytz.timezone(local_tz_id) now = datetime.now(local_tz) print(f"当前时间(带时区):{now}")
注意事项
- 这种依赖系统配置的方法,需要保证你的系统时区配置是正确的;
- Windows的映射表可能不全,如果你用到小众时区,需要自己补充对应的映射关系;
- 如果你需要跨平台兼容,可以再加个操作系统判断,比如用
sys.platform区分win32、linux、darwin,然后调用对应的函数。
内容的提问来源于stack exchange,提问作者jacobcan118
相关产品推荐
相关产品推荐

