如何在本地时区打印日期时间?
Posted
技术标签:
【中文标题】如何在本地时区打印日期时间?【英文标题】:How do I print a datetime in the local timezone? 【发布时间】:2010-11-09 19:48:45 【问题描述】:假设我有一个变量 t 设置为:
datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=<UTC>)
如果我说str(t)
,我会得到:
'2009-07-10 18:44:59.193982+00:00'
我怎样才能得到一个类似的字符串,除了打印在当地时区而不是UTC?
【问题讨论】:
相关:How to convert a python utc datetime to a local datetime using only python standard library? Python >= 3.6:使用astimezone()
,例如datetime.datetime(2010, 4, 27, 12, 0, 0, 0).astimezone().isoformat()
-> '2010-04-27T12:00:00+02:00'
【参考方案1】:
此脚本演示了几种使用astimezone()
显示本地时区的方法:
#!/usr/bin/env python3
import pytz
from datetime import datetime, timezone
from tzlocal import get_localzone
utc_dt = datetime.now(timezone.utc)
PST = pytz.timezone('US/Pacific')
EST = pytz.timezone('US/Eastern')
JST = pytz.timezone('Asia/Tokyo')
NZST = pytz.timezone('Pacific/Auckland')
print("Pacific time ".format(utc_dt.astimezone(PST).isoformat()))
print("Eastern time ".format(utc_dt.astimezone(EST).isoformat()))
print("UTC time ".format(utc_dt.isoformat()))
print("Japan time ".format(utc_dt.astimezone(JST).isoformat()))
# Use astimezone() without an argument
print("Local time ".format(utc_dt.astimezone().isoformat()))
# Use tzlocal get_localzone
print("Local time ".format(utc_dt.astimezone(get_localzone()).isoformat()))
# Explicitly create a pytz timezone object
# Substitute a pytz.timezone object for your timezone
print("Local time ".format(utc_dt.astimezone(NZST).isoformat()))
它输出以下内容:
$ ./timezones.py
Pacific time 2019-02-22T17:54:14.957299-08:00
Eastern time 2019-02-22T20:54:14.957299-05:00
UTC time 2019-02-23T01:54:14.957299+00:00
Japan time 2019-02-23T10:54:14.957299+09:00
Local time 2019-02-23T14:54:14.957299+13:00
Local time 2019-02-23T14:54:14.957299+13:00
Local time 2019-02-23T14:54:14.957299+13:00
从 python 3.6 开始,在没有时区对象的情况下调用 astimezone()
默认为本地区域 (docs)。这意味着您无需导入tzlocal
,只需执行以下操作:
#!/usr/bin/env python3
from datetime import datetime, timezone
utc_dt = datetime.now(timezone.utc)
print("Local time ".format(utc_dt.astimezone().isoformat()))
【讨论】:
这是最好的答案! 对了,python 3.6支持astimezone()
不带tz表示系统本地时间(refer)的特性。
@CodeUnsolved 感谢您澄清在没有 tz 对象的情况下调用 astimezone()
的行为。【参考方案2】:
从 python 3.2 开始,仅使用标准库函数:
u_tm = datetime.datetime.utcfromtimestamp(0)
l_tm = datetime.datetime.fromtimestamp(0)
l_tz = datetime.timezone(l_tm - u_tm)
t = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=l_tz)
str(t)
'2009-07-10 18:44:59.193982-07:00'
只需要使用l_tm - u_tm
或u_tm - l_tm
,具体取决于您希望显示为UTC 时间的+ 或- 小时。我在 MST,这就是 -07 的来源。更聪明的代码应该能够找出减去的方法。
并且只需要计算一次本地时区。这不会改变。至少在您切换到夏令时之前。
【讨论】:
这不考虑夏令时。 在基本设置中,它使用 UTC 和本地之间的增量作为纪元日期。其他任何事情都不能是“自动的”。在显示最后时间时,如果 当前 日期是 DST,或者如果显示的日期是/曾经/将是 DST,是否要使用 DST?所以这需要由周围的程序逻辑来决定,并在适当的时候调整l_tz。可能通过在 1 月 1 日与当前或目标年份的当前日期或目标日期之间进行类似的增量。【参考方案3】:前几天我写了这样一段话:
import time, datetime
def nowString():
# we want something like '2007-10-18 14:00+0100'
mytz="%+4.4d" % (time.timezone / -(60*60) * 100) # time.timezone counts westwards!
dt = datetime.datetime.now()
dts = dt.strftime('%Y-%m-%d %H:%M') # %Z (timezone) would be empty
nowstring="%s%s" % (dts,mytz)
return nowstring
所以对您来说有趣的部分可能是以“mytz=...”开头的那一行。 time.timezone 返回本地时区,尽管与 UTC 相比符号相反。所以它说“-3600”来表示UTC+1。
尽管它对夏令时(DST,见评论)一无所知,但我还是把它留给那些摆弄time.timezone
的人。
【讨论】:
-1。如果您处于使用 DST 的时区,这将有一半的时间返回错误的结果。time.timezone
包含在 DST 无效时使用的 UTC 偏移量,无论它当前是否有效。【参考方案4】:
认为您应该环顾四周:datetime.astimezone()
http://docs.python.org/library/datetime.html#datetime.datetime.astimezone
另请参阅 pytz 模块 - 它非常易于使用 - 例如:
eastern = timezone('US/Eastern')
http://pytz.sourceforge.net/
例子:
from datetime import datetime
import pytz
from tzlocal import get_localzone # $ pip install tzlocal
utc_dt = datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=pytz.utc)
print(utc_dt.astimezone(get_localzone())) # print local time
# -> 2009-07-10 14:44:59.193982-04:00
【讨论】:
那么如何获取当前本地时区? 不是 datetime.datetime(2009, 7, 10, 18, 44, 59, 193982) - 你需要什么? 这个答案是错误的。我住在英格兰,美国/东部不是本地时区。 @Muhail - 不,因为生成的对象不知道日期时间。你不知道你在哪个时区。 @Philluminati:tzlocal.get_localzone()
为您提供当地时区。【参考方案5】:
我使用这个函数datetime_to_local_timezone()
,它看起来过于复杂,但我发现没有更简单的函数版本可以将datetime
实例转换为本地时区,就像在操作系统中配置的那样 , 使用 当时有效的 UTC 偏移量:
import time, datetime
def datetime_to_local_timezone(dt):
epoch = dt.timestamp() # Get POSIX timestamp of the specified datetime.
st_time = time.localtime(epoch) # Get struct_time for the timestamp. This will be created using the system's locale and it's time zone information.
tz = datetime.timezone(datetime.timedelta(seconds = st_time.tm_gmtoff)) # Create a timezone object with the computed offset in the struct_time.
return dt.astimezone(tz) # Move the datetime instance to the new time zone.
utc = datetime.timezone(datetime.timedelta())
dt1 = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, utc) # DST was in effect
dt2 = datetime.datetime(2009, 1, 10, 18, 44, 59, 193982, utc) # DST was not in effect
print(dt1)
print(datetime_to_local_timezone(dt1))
print(dt2)
print(datetime_to_local_timezone(dt2))
此示例打印四个日期。对于两个时间点,一个在 2009 年 1 月,一个在 2009 年 7 月,每个时间点都在 UTC 和本地时区打印一次时间戳。这里,冬季使用 CET (UTC+01:00),夏季使用 CEST (UTC+02:00),它会打印以下内容:
2009-07-10 18:44:59.193982+00:00
2009-07-10 20:44:59.193982+02:00
2009-01-10 18:44:59.193982+00:00
2009-01-10 19:44:59.193982+01:00
【讨论】:
它看起来像 Python 3.3+ 代码(.timestamp()
方法)在这种情况下,您可以使用更简单的代码:dt.astimezone(tz=None)
。也使用timezone.utc
而不是timezone(datetime.timedelta())
。【参考方案6】:
我认为最好的方法是使用 datetime.tzinfo
文档中定义的 LocalTimezone
类(转到 http://docs.python.org/library/datetime.html#tzinfo-objects 并向下滚动到“示例 tzinfo 类”部分):
假设Local
是LocalTimezone
的一个实例
t = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=utc)
local_t = t.astimezone(Local)
然后str(local_t)
给出:
'2009-07-11 04:44:59.193982+10:00'
这就是你想要的。
(注意:这对您来说可能看起来很奇怪,因为我在澳大利亚新南威尔士州,比 UTC提前小时 10 或 11 小时)
【讨论】:
如果您根据日期时间文档定义了本地,这也可以:str(datetime.datetime.now(tz=Local))
请注意,这将打印当前有效的 UTC 偏移量的任何使用,这可能与 datetime
实例给出的时间(由于夏令时)。
LocalTimezone
如果基础time
实现不使用历史时区数据库(Windows 尤其属于此类),则过去日期可能会失败。
我认为 astimezone 的参数应该为空:t.astimezone()
以上是关于如何在本地时区打印日期时间?的主要内容,如果未能解决你的问题,请参考以下文章
如何在python烧瓶中获取具有本地时区的模板文件的修改日期
如何在熊猫中使用 read_csv 将时区感知日期时间作为时区天真的本地 DatetimeIndex 读取?