it-swarm-vi.tech

Làm cách nào để chuyển đổi giờ địa phương sang UTC bằng Python?

Làm cách nào để chuyển đổi một datetime chuỗi theo giờ địa phương thành chuỗi trong thời gian UTC?

Tôi chắc chắn tôi đã làm điều này trước đây, nhưng không thể tìm thấy nó và SO hy vọng sẽ giúp tôi (và những người khác) làm điều đó trong tương lai.

Làm rõ: Ví dụ: nếu tôi có 2008-09-17 14:02:00 trong múi giờ địa phương của mình (+10), tôi muốn tạo một chuỗi có thời gian UTC tương đương: 2008-09-17 04:02:00.

Ngoài ra, từ http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ , lưu ý rằng nói chung điều này là không thể như với DST và các vấn đề khác không có chuyển đổi duy nhất từ giờ địa phương đến giờ UTC.

248
Tom

Cảm ơn @rofly, chuyển đổi đầy đủ từ chuỗi sang chuỗi như sau:

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"))))

Tóm tắt của tôi về các hàm time/calendar:

time.strptime
chuỗi -> Tuple (không áp dụng múi giờ, do đó khớp với chuỗi)

time.mktime
Giờ địa phương Tuple -> giây kể từ Epoch (luôn luôn là giờ địa phương)

time.gmtime
giây kể từ Epoch -> Tuple trong UTC

và 

calendar.timegm
Tuple trong UTC -> giây kể từ Epoch

time.localtime
giây kể từ Epoch -> Tuple trong múi giờ địa phương

60
Tom

Đầu tiên, phân tích chuỗi thành một đối tượng datetime ngây thơ. Đây là một ví dụ của datetime.datetime không có thông tin múi giờ đính kèm. Xem tài liệu cho datetime.strptime để biết thông tin về phân tích chuỗi ngày.

Sử dụng mô đun pytz , đi kèm với một danh sách đầy đủ các múi giờ + UTC. Chỉ ra múi giờ cục bộ là gì, xây dựng một đối tượng múi giờ từ nó, và thao tác và gắn nó vào datetime ngây thơ.

Cuối cùng, sử dụng phương thức datetime.astimezone() để chuyển đổi thời gian thành UTC.

Mã nguồn, sử dụng múi giờ địa phương "America/Los_Angele", cho chuỗi "2001-2-3 10:11:12":

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)

Từ đó, bạn có thể sử dụng phương thức strftime() để định dạng thời gian UTC khi cần:

utc_dt.strftime ("%Y-%m-%d %H:%M:%S")
221
John Millikin

Hàm tcnow () của mô đun datetime có thể được sử dụng để lấy thời gian UTC hiện tại.

>>> import datetime
>>> utc_datetime = datetime.datetime.utcnow()
>>> utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2010-02-01 06:59:19'

Như liên kết được đề cập ở trên bởi Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ nói:

UTC là múi giờ không tiết kiệm thời gian ban ngày và vẫn là múi giờ không thay đổi cấu hình trong quá khứ.

Luôn đo và lưu trữ thời gian trong UTC .

Nếu bạn cần ghi lại thời gian đã được sử dụng, hãy lưu trữ riêng biệt. Không lưu trữ thời gian địa phương + thông tin múi giờ!

NOTE - Nếu bất kỳ dữ liệu nào của bạn nằm trong vùng sử dụng DST, hãy sử dụng pytz và xem câu trả lời của John Millikin.

Nếu bạn muốn có được thời gian UTC từ một chuỗi nhất định và bạn đủ may mắn ở một khu vực trên thế giới không sử dụng DST hoặc bạn có dữ liệu chỉ được bù từ UTC mà không áp dụng DST:

-> sử dụng giờ địa phương làm cơ sở cho giá trị bù:

>>> # 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'

-> Hoặc, từ một phần bù đã biết, sử dụng datetime.timedelta ():

>>> 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'

CẬP NHẬT:

Vì python 3.2 datetime.timezone khả dụng. Bạn có thể tạo một đối tượng datetime nhận biết múi giờ bằng lệnh bên dưới:

import datetime

timezone_aware_dt = datetime.datetime.now(datetime.timezone.utc)

Nếu bạn sẵn sàng thực hiện chuyển đổi múi giờ, hãy đọc điều này:

https://medium.com/ @

123
monkut

Dưới đây là tóm tắt về các chuyển đổi thời gian Python phổ biến.

Một số phương thức giảm phân số của giây và được đánh dấu bằng (s) . Thay vào đó, một công thức rõ ràng như ts = (d - Epoch) / unit có thể được sử dụng (cảm ơn jfs).

  • struct_time (UTC) → POSIX (s) :
    [.__.] calendar.timegm(struct_time)
  • Thời gian ngây thơ (cục bộ) → POSIX (s) :
    [.__.] calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    [.__.] (ngoại lệ trong quá trình chuyển đổi DST, xem nhận xét từ jfs)
  • Thời gian ngây thơ (UTC) → POSIX (s) :
    [.__.] calendar.timegm(dt.utctimetuple())
  • Aware datetime → POSIX (s) :
    [.__.] calendar.timegm(dt.utctimetuple())
  • POSIX → struct_time (UTC, s ):
    [.__.] time.gmtime(t)
    [.__.] (xem bình luận từ jfs)
  • Thời gian ngây thơ (cục bộ) → struct_time (UTC, s ):
    [.__.] stz.localize(dt, is_dst=None).utctimetuple()
    [.__.] (ngoại lệ trong quá trình chuyển đổi DST, xem nhận xét từ jfs)
  • Thời gian ngây thơ (UTC) → struct_time (UTC, s ):
    [.__.] dt.utctimetuple()
  • Aware datetime → struct_time (UTC, s ):
    [.__.] dt.utctimetuple()
  • POSIX → Naïve datetime (cục bộ):
    [.__.] datetime.fromtimestamp(t, None)
    [.__.] (có thể thất bại trong một số điều kiện nhất định, xem bình luận từ jfs bên dưới)
  • struct_time (UTC) → Naïve datetime (cục bộ, s ):
    [.__.] datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    [.__.] (không thể biểu thị giây nhuận, xem bình luận từ jfs)
  • Thời gian Naïve (UTC) → Thời gian Naïve (cục bộ):
    [.__.] dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • Aware datetime → Naïve datetime (cục bộ):
    [.__.] dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → Naïve datetime (UTC):
    [.__.] datetime.utcfromtimestamp(t)
  • struct_time (UTC) → Thời gian ngây thơ (UTC, s ):
    [.__.] datetime.datetime(*struct_time[:6])
    [.__.] (không thể biểu thị giây nhuận, xem bình luận từ jfs)
  • Thời gian Naïve (cục bộ) → Thời gian Naïve (UTC):
    [.__.] stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    [.__.] (ngoại lệ trong quá trình chuyển đổi DST, xem nhận xét từ jfs)
  • Aware datetime → Naïve datetime (UTC):
    [.__.] dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → Aware datetime:
    [.__.] datetime.fromtimestamp(t, tz)
    [.__.] (Có thể thất bại đối với các múi giờ không pytz)
  • struct_time (UTC) → Aware datetime (s) :
    [.__.] datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    [.__.] (không thể biểu thị giây nhuận, xem bình luận từ jfs)
  • Naïve datetime (cục bộ) → Aware datetime:
    [.__.] stz.localize(dt, is_dst=None)
    [.__.] (ngoại lệ trong quá trình chuyển đổi DST, xem nhận xét từ jfs)
  • Thời gian Naïve (UTC) → Aware datetime:
    [.__.] dt.replace(tzinfo=UTC)

Nguồn: taaviburns.ca

34
akaihola
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)

Nguồn: http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html

Ví dụ sử dụng từ bd808 : Nếu nguồn của bạn là đối tượng datetime.datetimet, hãy gọi là:

local_to_utc(t.timetuple())
23
Chuck Callebs

Tôi gặp may mắn với dateutil (được đề xuất rộng rãi trên SO cho các câu hỏi liên quan khác):

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')

(Mã được lấy từ câu trả lời này thành Chuyển đổi chuỗi thời gian UTC thành datetime cục bộ )

18
Yarin

Một ví dụ nữa với pytz, nhưng bao gồm localize (), đã lưu ngày của tôi.

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'
17

Tôi đã thành công nhất với python-dateutil :

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
12
Shu Wu
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'
7
Scipythonee

nếu bạn thích datetime.datetime:

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")
5
user235042

Bạn có thể làm điều đó với:

>>> from time import strftime, gmtime, localtime
>>> strftime('%H:%M:%S', gmtime()) #UTC time
>>> strftime('%H:%M:%S', localtime()) # localtime
4
Cristian Salamea

Để có được tiết kiệm ánh sáng ban ngày, vv.

Không có câu trả lời nào ở trên đặc biệt giúp tôi. Mã dưới đây hoạt động cho GMT.

def get_utc_from_local(date_time, local_tz=None):
    assert date_time.__class__.__== '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>)
2
Dantalion

Làm thế nào về - 

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

nếu giây là None thì nó chuyển đổi giờ địa phương thành thời gian UTC khác chuyển đổi thời gian đã qua thành UTC.

2
Anonymous fool

Sử dụng http://crsmithdev.com/arrow/

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') 

Thư viện này làm cho cuộc sống dễ dàng :)

2
Yash

Đơn giản

Tôi đã làm nó như thế này:

>>> 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

Fancy thực hiện

Nếu bạn muốn làm cho lạ mắt, bạn có thể biến điều này thành một functor:

class to_utc():
    utc_delta = datetime.utcnow() - datetime.now()

    def __call__(cls, t):
        return t + cls.utc_delta

Kết quả: 

>>> utc_converter = to_utc()
>>> print(utc_converter(datetime(2008, 9, 17, 14, 2, 0)))
2008-09-17 19:01:59.999996
1
uclatommy

Trong python3:

pip install python-dateutil

from dateutil.parser import tz

mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) 
0
spedy

Tôi tìm thấy câu trả lời tốt nhất cho một câu hỏi khác ở đây . Nó chỉ sử dụng các thư viện tích hợp python và không yêu cầu bạn nhập múi giờ cục bộ của bạn (một yêu cầu trong trường hợp của tôi) 

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)

Tôi đang đăng lại câu trả lời ở đây vì câu hỏi này xuất hiện trong google thay vì câu hỏi được liên kết tùy thuộc vào từ khóa tìm kiếm.

0
franksands