it-swarm-id.com

Bagaimana cara mengonversi waktu lokal ke UTC dengan Python?

Bagaimana cara mengonversi datetime string dalam waktu lokal menjadi string dalam waktu UTC?

Saya yakin saya pernah melakukan ini sebelumnya, tetapi tidak dapat menemukannya dan SO mudah-mudahan akan membantu saya (dan yang lain) melakukannya di masa depan.

Klarifikasi: Misalnya, jika saya memiliki 2008-09-17 14:02:00 di zona waktu lokal saya (+10), saya ingin membuat string dengan waktu UTC yang setara: 2008-09-17 04:02:00.

Juga, dari http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ , perhatikan bahwa secara umum ini tidak mungkin karena dengan DST dan masalah lain tidak ada konversi unik dari waktu setempat ke waktu UTC.

248
Tom

Terima kasih @rofly, konversi penuh dari string ke string adalah sebagai berikut:

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

Ringkasan saya dari fungsi time/calendar:

time.strptime
string -> Tuple (tidak ada zona waktu yang diterapkan, jadi cocok dengan string)

time.mktime
waktu lokal Tuple -> detik sejak Zaman (selalu waktu setempat)

time.gmtime
detik sejak Zaman -> Tuple di UTC

dan 

calendar.timegm
Tuple dalam UTC -> detik sejak Zaman

time.localtime
detik sejak Zaman -> Tuple di zona waktu lokal

60
Tom

Pertama, parsing string ke objek datetime yang naif. Ini adalah instance dari datetime.datetime tanpa informasi zona waktu yang terlampir. Lihat dokumentasi untuk datetime.strptime untuk informasi tentang penguraian string tanggal.

Gunakan modul pytz , yang dilengkapi dengan daftar zona waktu + UTC. Cari tahu apa zona waktu setempat, bangun objek zona waktu darinya, dan memanipulasi dan melampirkannya pada datetime yang naif.

Akhirnya, gunakan metode datetime.astimezone() untuk mengkonversi datetime ke UTC.

Kode sumber, menggunakan zona waktu lokal "America/Los_Angeles", untuk string "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)

Dari sana, Anda dapat menggunakan metode strftime() untuk memformat datetime UTC sesuai kebutuhan:

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

Fungsi utcnow () modul dat dat dapat digunakan untuk mendapatkan waktu UTC saat ini.

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

Seperti tautan yang disebutkan di atas oleh Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ mengatakan:

UTC adalah zona waktu tanpa waktu musim panas dan masih zona waktu tanpa perubahan konfigurasi di masa lalu.

Selalu mengukur dan menyimpan waktu dalam UTC

Jika Anda perlu merekam di mana waktu diambil, simpan secara terpisah. Jangan menyimpan waktu setempat + informasi zona waktu!

NOTE - Jika ada data Anda di wilayah yang menggunakan DST, gunakan pytz dan lihat jawaban John Millikin.

Jika Anda ingin mendapatkan waktu UTC dari string yang diberikan dan keberuntungan Anda cukup untuk berada di wilayah di dunia yang tidak menggunakan DST, atau Anda memiliki data yang hanya diimbangi dari UTC tanpa DST diterapkan:

-> menggunakan waktu lokal sebagai dasar untuk nilai offset:

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

-> Atau, dari offset yang diketahui, menggunakan 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'

Jika Anda siap untuk mengambil konversi zona waktu, baca ini:

https://medium.com/@eleroy/10-things-you-need-to-know-about-date-and-time-in-python-with-datetime-pytz-dateutil-timedelta-309bfbafb3f7

111
monkut

Berikut ringkasan konversi waktu Python umum.

Beberapa metode menjatuhkan pecahan detik, dan ditandai dengan (s). Formula eksplisit seperti ts = (d - Epoch) / unit dapat digunakan sebagai gantinya (terima kasih jfs).

  • struct_time (UTC) → POSIX (s):
    calendar.timegm(struct_time)
  • Waktu naif (lokal) → POSIX (s):
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    (pengecualian selama transisi DST, lihat komentar dari jfs)
  • Waktu naif (UTC) → POSIX (s):
    calendar.timegm(dt.utctimetuple())
  • Sadar datetime → POSIX (s):
    calendar.timegm(dt.utctimetuple())
  • POSIX → struct_time (UTC, s):
    time.gmtime(t)
    (lihat komentar dari jfs)
  • Waktu naif (lokal) → struct_time (UTC, s):
    stz.localize(dt, is_dst=None).utctimetuple()
    (pengecualian selama transisi DST, lihat komentar dari jfs)
  • Waktu naif (UTC) → struct_time (UTC, s):
    dt.utctimetuple()
  • Sadar datetime → struct_time (UTC, s):
    dt.utctimetuple()
  • POSIX → Data naif (lokal):
    datetime.fromtimestamp(t, None)
    (mungkin gagal dalam kondisi tertentu, lihat komentar dari jfs di bawah)
  • struct_time (UTC) → Waktu naif (lokal, s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    (tidak dapat mewakili detik kabisat, lihat komentar dari jfs)
  • Datad naif (UTC) → Datad naif (lokal):
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • Sadar datetime → Naïve datetime (lokal):
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → Dataran naif (UTC):
    datetime.utcfromtimestamp(t)
  • struct_time (UTC) → Waktu naif (UTC, s):
    datetime.datetime(*struct_time[:6])
    (tidak dapat mewakili detik kabisat, lihat komentar dari jfs)
  • Datad naif (lokal) → Datad naif (UTC):
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    (pengecualian selama transisi DST, lihat komentar dari jfs)
  • Sadar datetime → Naïve datetime (UTC):
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → Sadar datetime:
    datetime.fromtimestamp(t, tz)
    (mungkin gagal untuk zona waktu non-pytz)
  • struct_time (UTC) → Sadar waktu (s):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    (tidak dapat mewakili detik kabisat, lihat komentar dari jfs)
  • Naïve datetime (lokal) → Sadar datetime:
    stz.localize(dt, is_dst=None)
    (pengecualian selama transisi DST, lihat komentar dari jfs)
  • Naïve datetime (UTC) → Sadar waktu:
    dt.replace(tzinfo=UTC)

Sumber: taaviburns.ca

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

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

Contoh penggunaan dari bd808 : Jika sumber Anda adalah objek datetime.datetimet, panggil sebagai:

local_to_utc(t.timetuple())
23
Chuck Callebs

Saya beruntung dengan dateutil (yang direkomendasikan secara luas di SO untuk pertanyaan terkait lainnya):

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

(Kode diturunkan dari jawaban ini untuk Mengonversi string datetime UTC ke datetime lokal )

18
Yarin

Satu lagi contoh dengan pytz, tetapi termasuk localize (), yang menyelamatkan hari saya.

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

Saya paling sukses dengan 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

jika Anda lebih suka datetime. waktu:

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

Anda dapat melakukannya dengan:

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

Untuk menghemat waktu siang hari, dll.

Tidak ada jawaban di atas yang secara khusus membantu saya. Kode di bawah ini berfungsi untuk 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

Bagaimana tentang - 

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

jika detik None maka itu mengubah waktu lokal menjadi waktu UTC yang lain mengubah waktu yang dilewatkan menjadi UTC.

2
Anonymous fool

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

Perpustakaan ini memudahkan hidup :)

2
Yash

Sederhana

Saya melakukannya seperti ini:

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

Implementasi yang Mewah

Jika Anda ingin menjadi mewah, Anda bisa mengubahnya menjadi functor:

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

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

Hasil: 

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

Dalam python3:

pip install python-dateutil

from dateutil.parser import tz

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

Saya menemukan jawaban terbaik untuk pertanyaan lain di sini . Ini hanya menggunakan python built-in libraries dan tidak mengharuskan Anda untuk memasukkan zona waktu lokal Anda (persyaratan dalam kasus saya) 

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)

Saya memposting ulang jawabannya di sini karena pertanyaan ini muncul di google alih-alih pertanyaan terkait tergantung pada kata kunci pencarian.

0
franksands