Python:如何将日期时间/时间戳从一个时区转换为另一个时区?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31977563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python: How do you convert a datetime/timestamp from one timezone to another timezone?
提问by kfan
Specifically, given the timezone of my server (system time perspective) and a timezone input, how do I calculate the system time as if it were in that new timezone (regardless of daylight savings, etc)?
具体来说,鉴于我的服务器的时区(系统时间透视图)和时区输入,我如何计算系统时间,就好像它在新时区中一样(不管夏令时等)?
import datetime
current_time = datetime.datetime.now() #system time
server_timezone = "US/Eastern"
new_timezone = "US/Pacific"
current_time_in_new_timezone = ???
采纳答案by kfan
If you know your origin timezone and the new timezone that you want to convert it to, it turns out to be very straightforward:
如果您知道您的原始时区和要将其转换为的新时区,结果会非常简单:
1) Make a pytz.timezone
object for both the current timezone and the new timezone e.g. pytz.timezone("US/Pacific")
. If you don't know a timezone's official name, you can find a list of all official timezones by simply calling pytz.all_timezones
1)pytz.timezone
为当前时区和新时区创建一个对象,例如pytz.timezone("US/Pacific")
。如果您不知道时区的官方名称,只需拨打以下电话即可找到所有官方时区的列表pytz.all_timezones
2) Call .localize()
using the current timezone's pytz object with your datetime/timestamp as input to localize it to the current timezone. e.g. current_timezone.localize(timestamp)
2).localize()
使用当前时区的 pytz 对象和日期时间/时间戳作为输入调用以将其本地化到当前时区。例如current_timezone.localize(timestamp)
3) Finally, call .astimezone()
on the newly localized datetime/timestamp from step 2 with the desired new timezone's pytz object as input e.g. localized_timestamp.astimezone(new_timezone)
.
3) 最后,.astimezone()
使用所需的新时区的 pytz 对象作为输入调用步骤 2 中新本地化的日期时间/时间戳,例如localized_timestamp.astimezone(new_timezone)
.
Done!
完毕!
As a full example:
作为一个完整的例子:
import datetime
import pytz
# a timestamp I'd like to convert
my_timestamp = datetime.datetime.now()
# create both timezone objects
old_timezone = pytz.timezone("US/Eastern")
new_timezone = pytz.timezone("US/Pacific")
# two-step process
localized_timestamp = old_timezone.localize(my_timestamp)
new_timezone_timestamp = timezone_localized_timestamp.astimezone(new_timezone)
# or alternatively, as an one-liner
new_timezone_timestamp = old_timezone.localize(my_timestamp).astimezone(new_timezone)
Bonus: but if all you need is the current time in a specific timezone, you can conveniently pass that timezone directly into datetime.now() to get the current times directly:
奖励:但如果您只需要特定时区中的当前时间,您可以方便地将该时区直接传递给 datetime.now() 以直接获取当前时间:
datetime.datetime.now(new_timezone)
When it comes to needing timezones conversions generally, I would strongly advise that one should store all timestamps in your database in UTC, which has no daylight savings time (DST) transition. And as a good practice, one should always choose to enable time zone support (even if your users are all in a single time zone!). This will help you avoid the DST transition problem that plagues so much software today.
当谈到通常需要时区转换时,我强烈建议您将所有时间戳以 UTC 格式存储在您的数据库中,它没有夏令时 (DST) 转换。作为一种好的做法,应该始终选择启用时区支持(即使您的用户都在一个时区!)。这将帮助您避免困扰当今众多软件的 DST 转换问题。
Beyond DST, time in software can be generally quite tricky. To get a sense of just how difficult it is to deal with time in software in general, here is a potentially enlightening resource: http://yourcalendricalfallacyis.com
除了夏令时,软件中的时间通常非常棘手。为了大致了解在软件中处理时间是多么困难,这里有一个潜在的启发性资源:http: //yourcalendricalfallacyis.com
Even a seemingly simple operation as converting a datetime/timestamp into a date can become non-obvious. As this helpful documentationpoints out:
即使是将日期时间/时间戳转换为日期的看似简单的操作也可能变得不明显。正如这个有用的文档指出的那样:
A datetime represents a point in time. It's absolute: it doesn't depend on anything. On the contrary, a date is a calendaring concept. It's a period of time whose bounds depend on the time zone in which the date is considered. As you can see, these two concepts are fundamentally different.
日期时间代表一个时间点。这是绝对的:它不依赖于任何东西。相反,日期是一个日历概念。这是一段时间,其界限取决于考虑日期的时区。如您所见,这两个概念有着根本的不同。
Understanding this difference is a key step towards avoiding time-based bugs. Good luck.
了解这种差异是避免基于时间的错误的关键一步。祝你好运。
回答by jfs
How do you convert datetime/timestamp from one timezone to another timezone?
如何将日期时间/时间戳从一个时区转换为另一个时区?
There are two steps:
有两个步骤:
Create an aware datetime objects from the system time and timezonee.g., to get the current system time in the given timezone:
#!/usr/bin/env python from datetime import datetime import pytz server_timezone = pytz.timezone("US/Eastern") server_time = datetime.now(server_timezone) # you could pass *tz* directly
Note:
datetime.now(server_timezone)
works even during ambiguous timese.g., during DST transitions whileserver_timezone.localize(datetime.now())
may fail (50% chance).If you are sure that your input time exists in the server's timezone and it is unique then you could pass
is_dst=None
to assert that:server_time = server_timezone.localize(naive_time, is_dst=None)
It raises an exception for invalid times.
If it is acceptable to ignore upto a dayerror (though typically an error due to DST is around an hour) then you could dropis_dst
parameter:server_time = server_timezone.normalize(server_timezone.localize(naive_time))
.normalize()
is called to adjust non-existing times (local time in the gap, during "spring forward" transitions). If the time zone rules haven't changed; your server shouldn't generate non-existing times. See "Can I just always set is_dst=True?"Convert an aware datetime object to the target timezone
tz
:tz = pytz.timezone("US/Pacific") server_time_in_new_timezone = server_time.astimezone(tz)
从系统时间和时区创建一个感知日期时间对象,例如,获取给定时区中的当前系统时间:
#!/usr/bin/env python from datetime import datetime import pytz server_timezone = pytz.timezone("US/Eastern") server_time = datetime.now(server_timezone) # you could pass *tz* directly
注意:
datetime.now(server_timezone)
即使在不明确的时间也能工作,例如在 DST 转换期间,但server_timezone.localize(datetime.now())
可能会失败(50% 的几率)。如果您确定您的输入时间存在于服务器的时区中并且它是唯一的,那么您可以通过
is_dst=None
断言:server_time = server_timezone.localize(naive_time, is_dst=None)
它引发无效时间的异常。
如果可以忽略最多一天的错误(尽管通常由于 DST 导致的错误大约是一个小时),那么您可以删除is_dst
参数:server_time = server_timezone.normalize(server_timezone.localize(naive_time))
.normalize()
被调用来调整不存在的时间(间隙中的本地时间,在“spring forward”转换期间)。如果时区规则没有改变;您的服务器不应生成不存在的时间。请参阅“我可以始终设置 is_dst=True 吗?”将感知日期时间对象转换为目标时区
tz
:tz = pytz.timezone("US/Pacific") server_time_in_new_timezone = server_time.astimezone(tz)