如何将本地时间中的日期时间字符串转换为UTC时间中的字符串?
我肯定我以前做过,但找不到,所以希望将来能帮助我(和其他人)做到这一点。
说明:例如,如果我的本地时区(+10中有2008-09-17 14:02:00,我想生成一个等效UTC时间的字符串:2008-09-17 04:02:00。
另外,从http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/,请注意,一般来说,这是不可能的,因为DST和其他问题没有从本地时间到UTC时间的唯一转换。
- 请注意mktime()方法采用"本地时间"作为输入,这可能不是您所期望的,我使用了它,它把一切都弄乱了。请看一下这个链接
- 相反:如何只使用Python标准库将Python UTC日期时间转换为本地日期时间?
首先,将字符串解析为一个幼稚的datetime对象。这是一个没有附加时区信息的datetime.datetime实例。有关分析日期字符串的信息,请参阅datetime.strptime的文档。
使用pytz模块,该模块附带完整的时区+UTC列表。弄清楚本地时区是什么,从中构造一个时区对象,并操纵它并将其附加到原始的日期时间。
最后,使用datetime.astimezone()方法将日期时间转换为UTC。
源代码,使用本地时区"美国/洛杉矶",用于字符串"2001-2-3 10:11:12":
1 2 3 4 5
| import pytz, datetime
local = pytz.timezone ("America/Los_Angeles")
naive = datetime.datetime.strptime ("2001-2-3 10:11:12","%Y-%m-%d %H:%M:%S")
local_dt = local.localize(naive, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc) |
从这里,您可以根据需要使用strftime()方法来格式化UTC日期时间:
1
| utc_dt.strftime ("%Y-%m-%d %H:%M:%S") |
datetime模块的utcnow()函数可用于获取当前的UTC时间。
1 2 3 4
| >>> import datetime
>>> utc_datetime = datetime.datetime.utcnow()
>>> utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2010-02-01 06:59:19' |
正如汤姆提到的链接:http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/所说:
UTC is a timezone without daylight saving time and still a timezone
without configuration changes in the past.
Always measure and store time in UTC.
If you need to record where the time was taken, store that separately.
Do not store the local time + timezone information!
注意-如果您的任何数据位于使用DST的区域,请使用pytz并查看John Millikin的答案。
如果您想从给定的字符串中获得UTC时间,并且幸运地处于世界上一个不使用DST的地区,或者您的数据仅与未应用DST的UTC相偏移:
-->使用本地时间作为偏移值的基础:
1 2 3 4 5 6
| >>> # Obtain the UTC Offset for the current system:
>>> UTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now()
>>> local_datetime = datetime.datetime.strptime("2008-09-17 14:04:00","%Y-%m-%d %H:%M:%S")
>>> result_utc_datetime = local_datetime + UTC_OFFSET_TIMEDELTA
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00' |
-->or,从已知偏移量,使用datetime.timedelta():
1 2 3 4
| >>> UTC_OFFSET = 10
>>> result_utc_datetime = local_datetime - datetime.timedelta(hours=UTC_OFFSET)
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00' |
如果您准备好进行时区转换,请阅读以下内容:
https://medium.com/@eleroy/10-things-you-need-to-know-about-date-and-time-in-python-with-date time-pytz-dateutil-timedelta-309bfbafb3f7
- 它只转换当前时间,我需要使用任何给定时间(作为字符串)并转换为UTC。
- 如果utcnow()
- 如果使用标准偏移值,我认为这里不应该有什么关系。本地时间=UTC时间+UTC时间偏移量和UTC时间=本地时间-UTC时间偏移量。
- 它只适用于当前时间,因为由于DST,过去和将来的时间戳可能具有不同的UTC偏移量。
- 好点…如果你必须处理DST,你可能会使用约翰米利金提到的PYTZ。
- 在对utcnow()和now()的调用之间有一个零星的增量。这是一个危险的代码行,可能会导致后来出现奇怪的错误,如tzinfo.utcoffset() must return a whole number of minutes等。
- 我过去对它没什么问题,但你是对的。您可以将delta重新转换为:clean_delta=datetime.timedelta(hours=int(utc_offset_timedelta.total_seco‌&8203;nds()/60.0/60.0)),但请记住,有些地方像印度(utc+05:30)。
- 1。本地时区的UTC偏移量可能取决于日期时间;因此,将为当前时间计算的UTC偏移量应用于将来/过去的其他时间(例如DST转换之前/之后)可能不正确。2。除非您所说的是与问题无关的计算机时钟同步,否则就没有本地UTC。"什么时候是UTC"对地球上任何地方都有相同的单一答案(在评论时大约是晚上7点)。
- 另一种摆脱delta betteen utcnow()和now()的方法是:UTC_OFFSET_TIMEDELTA = datetime.utcnow().replace(minute=0, second=0, microsecond=0) - datetime.now().replace(minute=0, second=0, microsecond=0)。注意:如果一次是从前一分钟到后一分钟,它可能仍然会偶尔出错。
谢谢@rofly,字符串到字符串的完整转换如下:
1 2 3
| time.strftime("%Y-%m-%d %H:%M:%S",
time.gmtime(time.mktime(time.strptime("2008-09-17 14:04:00",
"%Y-%m-%d %H:%M:%S")))) |
我对time和calendar功能的总结:
time.strptime字符串-->元组(未应用时区,因此与字符串匹配)
time.mktime本地时间元组——>自epoch以来的秒数(始终为本地时间)
time.gmtime从epoch开始的秒数——>以UTC表示的元组
和
calendar.timegmtuple(UTC)->自epoch以来的秒数
time.localtime自epoch以来的秒数——>本地时区中的元组
- (always local time)似乎是错误的:mktime()的输入是本地时间,输出是epoch(1970-01-01 00:00:00 +0000 (UTC)以来的秒数,不依赖于时区。
- 在DST转换过程中,也有50%的机会失败。查看本地时间的问题
下面是常见的Python时间转换的摘要。
有些方法会删除秒的分数,并用(s)标记。可以使用一个明确的公式,如ts = (d - epoch) / unit(谢谢JFS)。
- 结构时间(UTC)→位置:calendar.timegm(struct_time)。
- Na?ve datetime(本地)→posix(s):calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())(DST转换期间的异常,请参阅JFS的注释)
- Na?ve datetime(UTC)→posix(s):calendar.timegm(dt.utctimetuple())
- aware datetime→posix(s):calendar.timegm(dt.utctimetuple())
- posix→结构时间(utc,s):time.gmtime(t)(见JFS评论)
- Na?ve datetime(本地)→结构时间(UTC,S):stz.localize(dt, is_dst=None).utctimetuple()(DST转换期间的异常,请参阅JFS的注释)
- Na?ve datetime(UTC)→结构时间(UTC,S):dt.utctimetuple()。
- aware datetime→结构时间(UTC,S):dt.utctimetuple()。
- POSIX~Na?ve datetime(本地):datetime.fromtimestamp(t, None)(在某些情况下可能会失败,请参阅下面JFS的注释)
- 结构时间(UTC)→不适用?ve datetime(local,s):datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)(不能代表闰秒,见jfs的注释)
- Na?ve datetime(UTC)→na?ve日期时间(本地):dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)。
- 知道日期时间吗?不知道?ve日期时间(本地):dt.astimezone(tz).replace(tzinfo=None)。
- POSIX~Na?ve日期时间(UTC):datetime.utcfromtimestamp(t)。
- 结构时间(UTC)→不适用?ve datetime(UTC,S):datetime.datetime(*struct_time[:6])(不能代表闰秒,见JFS的注释)
- Na?ve datetime(本地)→na?ve datetime(UTC):stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)(DST转换期间的异常,请参阅JFS的注释)
- 知道日期时间吗?不知道?ve日期时间(UTC):dt.astimezone(UTC).replace(tzinfo=None)。
- posix→aware datetime:datetime.fromtimestamp(t, tz)(对于非pytz时区可能失败)
- 结构时间(UTC)→感知日期时间(S):datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)(不能代表闰秒,见JFS评论)
- Na?ve datetime(本地)→aware datetime:stz.localize(dt, is_dst=None)(DST转换期间的异常,请参阅来自JFS的注释)
- Na?ve datetime(UTC)→aware datetime:dt.replace(tzinfo=UTC)
资料来源:taaviburns.ca
- (1)如果本地时区在t处具有不同的UTC偏移量,并且C库无法访问给定平台上的TZ数据库,则fromtimestamp(t, None)可能会失败。您可以使用tzlocal.get_localzone()以可移植的方式提供TZdata。(2)对于非PYTZ时区,fromtimestamp(t, tz)可能会失败。(3)你失踪了。(4)基于timegm()、utctimetuple()、struct_time的解只差一秒。您可以使用一个显式的公式,例如:ts = (d - epoch) / unit。
- (5)stz.localize(dt, is_dst=None)对不明确或不存在的本地时间(如DST转换期间)提出了例外。为了避免例外,使用可能返回不精确结果的stz.normalize(stz.localize(dt))。(6)datetime()不能表示闰秒。先把struct_time转换为"从新纪元开始的秒数",作为解决方法。(7)与calendar.timegm()不同的是,如果使用"正确"时区,time.gmtime(t)可能需要非posix输入。如果输入是posix,则使用显式公式:gmtime = lambda t: datetime(1970,1,1, tzinfo=utc) + timedelta(seconds=t)。
- 我希望这是在一张桌子上,更容易阅读(在链接中)
- @Michaelchirico,这个答案指出,"我们不(也不会)允许使用
标签。对不起的。这是故意的,也是故意的。如果您需要一个快速而脏的"表",请使用和ascii布局。"我不认为ascii表比上面的列表更可读。
- 好吧,那太不幸了。不管怎样,你有我的赞成票…也许在你的答案中引用链接中的表格?
- @Michaelchirico,答案已经包含了taavi burns原始表格的链接。
1 2 3 4 5 6 7
| def local_to_utc(t):
secs = time.mktime(t)
return time.gmtime(secs)
def utc_to_local(t):
secs = calendar.timegm(t)
return time.localtime(secs) |
来源:http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html
来自BD808的示例用法:如果源是datetime.datetime对象t,则调用为:
1
| local_to_utc(t.timetuple()) |
- 如果源是datetime.datetime对象t,则调用为:local_to_utc(t.timetuple())
- .timetuple()调用将tm_isdst设置为-1;dst转换期间mktime()失败的概率为50%。
- 查克的解决方案会丢失毫秒信息。
我和dateutil的关系很好(对于其他相关问题,它被广泛推荐为so):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from datetime import *
from dateutil import *
from dateutil.tz import *
# METHOD 1: Hardcode zones:
utc_zone = tz.gettz('UTC')
local_zone = tz.gettz('America/Chicago')
# METHOD 2: Auto-detect zones:
utc_zone = tz.tzutc()
local_zone = tz.tzlocal()
# Convert time string to datetime
local_time = datetime.strptime("2008-09-17 14:02:00", '%Y-%m-%d %H:%M:%S')
# Tell the datetime object that it's in local time zone since
# datetime objects are 'naive' by default
local_time = local_time.replace(tzinfo=local_zone)
# Convert time to UTC
utc_time = local_time.astimezone(utc_zone)
# Generate UTC time string
utc_string = utc_time.strftime('%Y-%m-%d %H:%M:%S') |
(代码是从该答案派生的,用于将UTC日期时间字符串转换为本地日期时间)
- 如果本地时区的UTC偏移量不同(与DST转换无关),则在不使用历史时区数据库(尤其是Windows)的系统上,dateutil可能在过去的日期失败。可以使用pytz+tzlocal。
- @约翰塞巴斯蒂安-没听说过-我们在哪里可以得到更多的信息?
- 以Windows Machine为例,设置过去具有不同UTC偏移量的任何时区,例如欧洲/莫斯科。将结果与Pytz进行比较。另外,您可以测试这个bug,即使在Ubuntu上也会失败,尽管在这种情况下,我不确定是否正确地使用了API。
- 产量是多少?请张贴输出。
还有一个例子是pytz,但是包含localize(),这节省了我一天的时间。
1 2 3 4 5 6 7 8 9
| import pytz, datetime
utc = pytz.utc
fmt = '%Y-%m-%d %H:%M:%S'
amsterdam = pytz.timezone('Europe/Amsterdam')
dt = datetime.datetime.strptime("2012-04-06 10:00:00", fmt)
am_dt = amsterdam.localize(dt)
print am_dt.astimezone(utc).strftime(fmt)
'2012-04-06 08:00:00' |
我在python dateutil上取得了最大的成功:
1 2 3 4 5
| from dateutil import tz
def datetime_to_utc(date):
"""Returns date in UTC w/o tzinfo"""
return date.astimezone(tz.gettz('UTC')).replace(tzinfo=None) if date.tzinfo else date |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import time
import datetime
def Local2UTC(LocalTime):
EpochSecond = time.mktime(LocalTime.timetuple())
utcTime = datetime.datetime.utcfromtimestamp(EpochSecond)
return utcTime
>>> LocalTime = datetime.datetime.now()
>>> UTCTime = Local2UTC(LocalTime)
>>> LocalTime.ctime()
'Thu Feb 3 22:33:46 2011'
>>> UTCTime.ctime()
'Fri Feb 4 05:33:46 2011' |
- mktime(dt.timetuple())在DST转换期间可能会失效。文档中有LocalTimezone(适用于最新的时区定义,但对于过去的日期可能失败(与dst无关))。
如果您喜欢datetime.datetime:
1 2 3 4
| dt = datetime.strptime("2008-09-17 14:04:00","%Y-%m-%d %H:%M:%S")
utc_struct_time = time.gmtime(time.mktime(dt.timetuple()))
utc_dt = datetime.fromtimestamp(time.mktime(utc_struct_time))
print dt.strftime("%Y-%m-%d %H:%M:%S") |
- 当然,但我不明白你为什么会喜欢。它需要额外的导入和比我的版本多3个函数调用…
- %Z和%Z仍打印空白。
- 这是不正确的。如果本地时区不是UTC,则失败。mktime()希望本地时间作为输入。fromtimestamp()返回本地时间,而不是UTC。如果您修复它,那么会看到这些额外的问题(如dateutil,只有stdlib的解决方案可能会失败)
你可以用以下方法来做:
1 2 3
| >>> from time import strftime, gmtime, localtime
>>> strftime('%H:%M:%S', gmtime()) #UTC time
>>> strftime('%H:%M:%S', localtime()) # localtime |
使用http://crsmithdev.com/arrow/
1 2 3
| arrowObj = arrow.Arrow.strptime('2017-02-20 10:00:00', '%Y-%m-%d %H:%M:%S' , 'US/Eastern')
arrowObj.to('UTC') or arrowObj.to('local') |
这个图书馆使生活变得容易:)
- 箭头太棒了:arrow.get(datetime.now(),'local').to('utc').naive
怎么样?
1
| time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds)) |
如果秒是None,则将本地时间转换为UTC时间,否则将传入的时间转换为UTC。
简单的我是这样做的:
1 2 3 4
| >>> utc_delta = datetime.utcnow()-datetime.now()
>>> utc_time = datetime(2008, 9, 17, 14, 2, 0) + utc_delta
>>> print(utc_time)
2008-09-17 19:01:59.999996 |
花式实现
如果你想变得花哨,你可以把它变成一个函数:
1 2 3 4 5
| class to_utc():
utc_delta = datetime.utcnow() - datetime.now()
def __call__(cls, t):
return t + cls.utc_delta |
结果:
1 2 3
| >>> utc_converter = to_utc()
>>> print(utc_converter(datetime(2008, 9, 17, 14, 2, 0)))
2008-09-17 19:01:59.999996 |
- 这不适用于夏令时-例如,如果当前是夏季,而您转换的日期是冬季。问题是如何转换存储为字符串的日期…
- FYI。这种方法最大的问题(除了日光节约)是delta将关闭的几毫秒。我所有的日历邀请将在1分钟后显示为"关闭"。
用于白天照明等。
以上的回答对我都没有特别的帮助。下面的代码适用于GMT。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| def get_utc_from_local(date_time, local_tz=None):
assert date_time.__class__.__name__ == 'datetime'
if local_tz is None:
local_tz = pytz.timezone(settings.TIME_ZONE) # Django eg,"Europe/London"
local_time = local_tz.normalize(local_tz.localize(date_time))
return local_time.astimezone(pytz.utc)
import pytz
from datetime import datetime
summer_11_am = datetime(2011, 7, 1, 11)
get_utc_from_local(summer_11_am)
>>>datetime.datetime(2011, 7, 1, 10, 0, tzinfo=<UTC>)
winter_11_am = datetime(2011, 11, 11, 11)
get_utc_from_local(winter_11_am)
>>>datetime.datetime(2011, 11, 11, 11, 0, tzinfo=<UTC>) |
我在这里找到了另一个问题的最佳答案。它只使用Python内置库,不需要输入本地时区(在我的例子中是一个要求)。
1 2 3 4 5 6
| import time
import calendar
local_time = time.strptime("2018-12-13T09:32:00.000","%Y-%m-%dT%H:%M:%S.%f")
local_seconds = time.mktime(local_time)
utc_time = time.gmtime(local_seconds) |
我在这里重新发布答案,因为这个问题是在谷歌中弹出的,而不是根据搜索关键字链接的问题。
在Python 3中:
pip install python-dateutil
1 2 3
| from dateutil.parser import tz
mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) |
- 这似乎不起作用,它引发了一个ValueError异常:ValueError:AsTimeZone()不能应用于原始日期时间
- 应该是:from dateutil import tz 。
在这种情况下…派兹是最好的自由党
1 2 3 4
| import pytz
utc = pytz.utc
yourdate = datetime.datetime.now()
yourdateutc = yourdate.astimezone(utc).replace(tzinfo=None) |
- 这没有帮助,问题是要将给定的本地时间字符串转换为UTC字符串。
- -1:astimezone() cannot be applied to a naive datetime。
- 这不管用。