python - 远程主机时区与本地时区

1 投票
1 回答
956 浏览
提问于 2025-04-16 16:30

我正在为远程日志监控构建一个网页前端,
需要管理大约10个不同的地理位置,我遇到了你们中一些人已经碰到的麻烦。

有没有办法从远程的HPUX系统获取以下信息:

  • 时区信息(国家/城市)
  • UTC + 时差(我可以很容易从时区信息中获取这个)

到目前为止,我能得到的最好结果是操作系统的缩写时区,
(这是否足够让我通过一个静态的pytz.common_timezones集合,逐步对比远程时间并将缩写时区转换回国家/城市,还是我完全走错了方向?)

在获取国家/城市后,我可以轻松得到时差(但我还没有获取到)

datetime.now(pytz.timezone('Asia/Dili')).strftime('%Z %z')

'TLT +0900'

  • 获取远程缩写时区,

(Linux的时区处理要合理得多)

grep "ZONE=" /etc/sysconfig/clock  

输出像,
ZONE="Europe/London"
而HP-UX的/etc/TIMEZONE使用缩写时区,比如
TZ=CAT-2

我会使用echo $TZ,这样会输出一些更有用的数据,比如CAT-2,但有些远程的HP-UX系统甚至没有配置这个,因此我不得不依赖模糊的RFC822日期,

date +%z  

CAT

我查看了pytz、datetime.datetime和email.Utils,但考虑到直接从缩写时区转换为时区信息的国家/城市是不可能的(pytz支持反向转换),
我是不是应该放弃这个像唐吉诃德一样的任务,不去自动发现远程时区,而是在接受用户输入注册远程主机时,直接添加一个国家/城市的下拉列表?

编辑(部分解决方案)

基于@Mike Pennington的回答

from datetime import datetime as dt
from datetime import timedelta as td
from dateutil.relativedelta import *
from email.Utils import mktime_tz, parsedate_tz

hpux_remote_date = 'Thu Apr 28 18:09:20 TLT 2011'
utctimestamp = mktime_tz(parsedate_tz( hpux_remote_date ))  

hpux_dt = dt.fromtimestamp( utctimestamp )
delta_offset = relativedelta(dt.utcnow(), hpux_dt)

hpux_utc = hpux_dt + delta_offset

# Sanity checking to ensure we are correct...
hpux_dt
datetime.datetime(2011, 4, 28, 18, 9, 20)
hpux_utc
datetime.datetime(2011, 4, 28, 9, 9, 22, 229148)

1 个回答

3

你可以这样找到你的GMT时差...

不考虑夏令时的GMT时差

(time.localtime()[3] - time.localtime()[8]) - time.gmtime()[3]

我在中部时间(GMT - 6),所以在我的系统上,这个计算结果是-6

考虑夏令时的GMT时差

(time.localtime()[3]) - time.gmtime()[3]

在我的系统上,这个计算结果是-5

可能最简单的办法是用第二种方法,把本地的HPUX时间转换成GMT,然后根据需要用pytz进行处理。

编辑

如果你在处理远程(非GMT)时间戳的文本表示,直接使用日期时间对象可能更简单... 我没有HPUX的环境,但我假设日期字符串和我的debian squeeze系统类似。

>>> from datetime import datetime as dt
>>> from datetime import timedelta as td
>>> # using os.popen() to simulate the results of a HPUX shell 'date'...
>>> # substitute the real HPUX shell date string in hpux_date
>>> hpux_date = os.popen('date').read().strip()
>>> hpux_dt = dt.strptime(hpux_date, '%a %b %d %H:%M:%S %Z %Y')
>>> # Rounding to the nearest hour because there *will* be slight delay
>>> # between shell string capture and python processing
>>> offset_seconds = ((dt.utcnow() - hpux_dt).seconds//3600)*3600
>>> hpux_gmt = hpux_dt + td(0,offset_seconds)
>>> # Sanity checking to ensure we are correct...
>>> hpux_gmt
datetime.datetime(2011, 4, 27, 17, 21, 58)
>>> hpux_dt
datetime.datetime(2011, 4, 27, 12, 21, 58)
>>> hpux_date
'Wed Apr 27 12:21:58 CDT 2011'
>>>

撰写回答