在Python中获取系统本地时区

19

看起来很奇怪,但我无法找到一种使用Python的pandas/pytz轻松查找本地时区的方法。

我可以这样做:

>>> pd.Timestamp('now', tz='utc').isoformat()
Out[47]: '2016-01-28T09:36:35.604000+00:00'
>>> pd.Timestamp('now').isoformat()
Out[48]: '2016-01-28T10:36:41.830000'
>>> pd.Timestamp('now').tz_localize('utc') - pd.Timestamp('now', tz='utc')
Out[49]: Timedelta('0 days 01:00:00')

这将给我时区,但这可能不是最好的方法... 在pytz或pandas中是否有命令可以获取系统时区?(最好在python 2.7中)


如果不是重复问题的话,以下是有关编程的内容:Python:找出本地时区 - FObersteiner
1
该死的Python没有内置的方法来做到这一点。 - huang
5个回答

28

我认为使用pytzpandas无法实现这一点,但您始终可以安装python-dateutiltzlocal

from dateutil.tz import tzlocal
datetime.now(tzlocal())
或者
from tzlocal import get_localzone
local_tz = get_localzone()

6
如果你想要获取实际的时区名称,可以使用datetime.now(tzlocal()).tzname()。它会输出一个三个字母的时区代码,比如山地时区的代码是MST - MikeyE

21

time.timezone应该有效。

本地(非夏令时)时区相对于UTC的偏移量,以秒为单位表示(在大部分西欧为负,在美国为正,在英国为零)。

将其除以3600将会得到以小时为单位的偏移量:

import time

print(time.timezone / 3600.0)

这不需要任何额外的Python库。


7
这没有考虑到夏令时的影响。 - CoffeeTableEspresso
4
正确,这会给出非DST本地时区。如果您需要知道夏令时是否激活,可以使用 time.localtime( ).tm_isdst > 0 - Martin Evans

17

我发现在许多情况下这个方法有效:(自Python 3.6开始)

from datetime import datetime

# use this extension and it adds the timezone
tznow = datetime.now().astimezone()
print(tznow.isoformat())
2020-11-05T06:56:38.514560-08:00

# It shows that it does have a valid timezone
type(tznow.tzinfo)
<class 'datetime.timezone'>

我觉得这很方便,因为它不依赖于外部包。 它似乎只在Python3中运行(而不是Python2)


3

time 模块涵盖了许多与操作系统本地时间相关的设置。

import time

# Since Python 3.3
local_time = time.localtime()         # returns a `time.struct_time`
tzname_local = local_time.tm_zone     # 'EST'
dst = local_time.tm_isdst             # _from docs_: may be set to 1 when daylight savings time is in effect, 
                                      # and 0 when it is not. A value of -1 indicates that this is not known, 
                                      # and will usually result in the correct state being filled in.

在支持struct tm相应属性的C库平台上,可以使用tm_gmtofftm_zone属性。
详见:https://docs.python.org/3/library/time.html#time.struct_time
# At least from Python 2.7.18
local_tzname = time.tzname            # 'EST'

一个由两个字符串组成的元组:第一个字符串是本地非夏令时(Non-DST)时区的名称,第二个字符串是本地夏令时(DST)时区的名称。如果没有定义夏令时时区,则不应使用第二个字符串。 参见:https://docs.python.org/2.7/library/time.html#time.tzname)

另一个技巧是使用datetime.now().astimezone(),如此处所述和为什么在Python 2.x上会失败的原因

from datetime import datetime

# Python 3 will return a datetime with local timezone,
local_now = datetime.now().astimezone()    

# Doesn't work on python 2.x 
# datetime.now().astimezone()                -> TypeError: Required argument 'tz' (pos 1) not found
# datetime.now().astimezone(dateutil.tz.UTC) -> ValueError: astimezone() cannot be applied to a naive datetime

local_tz = local_now.tzinfo  # datetime.timezone
local_tzname = local_tz.tzname(local_now)
print(local_tzname) 

请注意,time.localtime().tm_zone 返回的是一个缩写,如果您将其传递给许多库(通常是使用 pytz 作为后端的任何库),则该缩写通常不可重用,因为某些缩写不是唯一的datetime 方法返回一个与 UTC 的时间差以秒为单位的对象,这更可靠。 - undefined

1

虽然它没有使用pytz/Pandas,但其他答案也没有使用,所以我想我应该发布一下我在mac/linux上使用的内容:

import subprocess
timezone = subprocess.check_output("date +%Z")

与其他答案相比的优点:尊重夏令时,无需安装额外的库。


2
解析外部命令的输出是脆弱的,除非指定了输出格式,否则可能会在输出格式更改时出现错误。最好使用date +%Z的输出而不进行解析。 - musiphil
1
生成一个新进程会消耗系统更多的资源。虽然这个答案是正确的,但在I/O密集型系统中应该是最后的选择。当然,这是相对的: 例如,在服务器端HTTP处理程序中进行此子进程调用可能会使您的应用程序更加敏感于DDoS攻击。如果将其放在lambda中,它也会使调用时间更长,成本更高。但是,如果您只想编写一个快速脚本,不需要与Windows兼容,那么这个答案应该是更快捷的完成方式。 - Gabriel Falcão
2
不确定其他版本的Python是否会有所不同,但我正在使用3.7.3,并且需要以下语法:timezone = subprocess.check_output(["date", "+%Z"]); 我猜默认情况下不使用shell,因此在单个字符串中包含参数只会使函数查找一个同名文件,从而失败。 - Eric Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接