Ia bekerja untuk zona waktu apa pun termasuk yang mengamati daylight saving time (DST) yaitu, ia bekerja untuk zona waktu yang mungkin memiliki offset utc yang berbeda pada waktu yang berbeda (offset utc yang tidak tetap). Jangan gunakan tz.localize(datetime.now())- ini mungkin gagal selama transisi akhir-DST ketika waktu setempat ambigu.
Tetapi tidak ada alasan yang baik untuk menjadi naif zona waktu - ini ditentukan sebagai UTC. Mengapa Anda perlu mencari perpustakaan pihak ketiga untuk membuatnya berfungsi dengan baik?
Mark Ransom
4
Saya setuju; bagi saya masa 'naif' sama sekali tidak berguna. Ada diskusi pada daftar python saat ini tentang menambahkan pytz ke stdlib; masalahnya bukan perizinan tetapi fakta bahwa data zona waktu sering diperbarui (yang tidak bisa dilakukan oleh Python sendiri). Juga pytz tidak mengimplementasikan antarmuka tzinfo dengan cara yang diharapkan sehingga Anda bisa mendapatkan kesalahan jika Anda mencoba menggunakan beberapa zona waktu kota di astimezone. Jadi datetime tidak hanya tidak memiliki zona waktu asli, tetapi satu-satunya implementasi tzinfo yang tersedia secara luas adalah tidak sesuai dengan standar yang seharusnya.
bobince
5
@obobince Mengapa pytz dan pustaka datetime standar tidak cocok untuk Anda? Inti Python dan pytz berkembang sebagai proyek independen mengurangi kompleksitas logistik untuk tim inti. Ya, mengurangi kompleksitas untuk tim inti Python meningkatkan kompleksitas untuk semua pengguna Python yang perlu berurusan dengan zona waktu tetapi, saya percaya mereka membuat keputusan ini untuk alasan yang bagus. Aturan "Perpustakaan standar tidak memiliki instance tzinfo ..." bagus karena sederhana, mengapa membuat pengecualian di sini?
Yang mana yang lebih disukai? datetime.now(timezone.utc)atau datetime.utcnow(timezone.utc)?
Jesse Webb
8
datetime.utcnow()tidak membutuhkan argumen. Jadi harus begitu datetime.now(timezone.utc).
Craig McQueen
1
datetime.now()akan mengembalikan waktu mesin tetapi datetime.utcnow()akan mengembalikan waktu UTC yang sebenarnya.
Babu
13
@Babu: datetime.utcnow()tidak disetel tzinfountuk menunjukkan bahwa itu UTC. Tetapi datetime.now(datetime.timezone.utc)mengembalikan waktu UTC dengantzinfo set.
Craig McQueen
@CraigMcQueen Jadi, jika kita melewatkan tzobjek di konstruktor sekarang, ia akan mengembalikan waktu zona waktu itu? Baik! Terima kasih telah menunjukkan.
Babu
71
Pustaka Python standar tidak menyertakan kelas tzinfo (tetapi lihat pep 431 ). Saya hanya bisa menebak alasannya. Secara pribadi saya pikir itu adalah kesalahan untuk tidak memasukkan kelas tzinfo untuk UTC, karena yang satu itu cukup tidak kontroversial untuk memiliki implementasi standar.
Sunting: Meskipun tidak ada implementasi di perpustakaan, ada satu yang diberikan sebagai contoh dalam tzinfodokumentasi .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)# A UTC class.class UTC(tzinfo):"""UTC"""def utcoffset(self, dt):return ZERO
def tzname(self, dt):return"UTC"def dst(self, dt):return ZERO
utc = UTC()
Untuk menggunakannya, untuk mendapatkan waktu saat ini sebagai objek datetime sadar:
from datetime import datetime
now = datetime.now(utc)
Ada datetime.timezone.utcdalam Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Cari tahu mengapa kelas ini tidak disediakan di tempat pertama (dan, yang lebih penting, digunakan untuk datetimeobjek yang dibuat oleh utcnow()) ...
André Caron
17
Objek zona waktu timezone.utcakhirnya telah ditambahkan ke Python 3.2. Untuk kompatibilitas mundur, utcnow()masih mengembalikan objek waktu kurang zona, tetapi Anda bisa mendapatkan apa yang Anda inginkan dengan menelepon now(timezone.utc).
mhsmith
4
@rgove, itulah jenis kesalahan yang seharusnya menjadi permainan adil bagi Python 3. Mereka seharusnya tidak khawatir tentang kompatibilitas ke belakang. Ada contoh lain yang saya baca dalam beberapa hari terakhir - structmodul akan melakukan konversi otomatis dari Unicode ke bytestring, dan keputusan terakhir adalah untuk memutus kompatibilitas dengan versi Python 3 sebelumnya untuk mencegah keputusan buruk dari maju.
@ LS ya, pytzadalah sumber yang bagus. Pada saat saya mengedit jawaban saya untuk dimasukkan ke dalam kode contoh, orang lain telah menyarankannya dan saya tidak ingin mencuri guntur mereka.
Mark Ransom
20
The pytzModul adalah salah satu pilihan, dan ada lagi python-dateutil, yang meskipun juga paket pihak ketiga, mungkin sudah tersedia, tergantung pada dependensi lain dan sistem operasi.
Saya hanya ingin memasukkan metodologi ini untuk referensi - jika Anda sudah menginstal python-dateutiluntuk tujuan lain, Anda dapat menggunakannya tzinfodaripada menduplikasipytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Saya cenderung setuju bahwa panggilan utcnowharus mencakup informasi zona waktu UTC. Saya menduga bahwa ini tidak termasuk karena pustaka datetime bawaan default ke naet data untuk kompatibilitas lintas.
Saya menggunakan panggilan datetime.datetime.utcfromtimestamp (), dan perlu menambahkan tzinfo, Solusi kedua bekerja untuk saya: utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
Sejak program saya sudah mengimpor dateutiluntuk dateutil.parser, aku suka solusi ini yang terbaik. Itu yang sederhana seperti: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc()). Biola!!
Memang, API datetime Python selalu mengembalikan objek datetime yang tidak disadari, yang sangat disayangkan. Memang, begitu Anda mendapatkan salah satu objek ini, tidak ada cara untuk mengetahui zona waktu itu, oleh karena itu objek-objek ini cukup "tidak berguna" sendiri.
Sayangnya, meskipun Anda dapat menggunakan utcnow(), Anda masih tidak akan melihat info zona waktu, seperti yang Anda temukan.
Rekomendasi:
Selalu gunakan datetimeobjek sadar , yaitu dengan informasi zona waktu. Itu memastikan Anda dapat membandingkannya secara langsung (objek sadar dan tidak sadar datetime
tidak sebanding) dan akan mengembalikannya dengan benar kepada pengguna. Leverage pytz untuk memiliki objek zona waktu.
Gunakan ISO 8601 sebagai format string input dan output. Gunakan datetime.datetime.isoformat()untuk mengembalikan cap waktu sebagai string yang diformat menggunakan format itu, yang mencakup informasi zona waktu.
Jika Anda perlu mengurai string yang berisi cap waktu berformat ISO 8601, Anda dapat mengandalkan iso8601, yang mengembalikan cap waktu dengan informasi zona waktu yang benar. Ini membuat cap waktu secara langsung dapat dibandingkan.
Rekomendasi ini sedikit menyesatkan. Aturan praktisnya adalah, jangan pernah berurusan dengan zona waktu. Selalu simpan dan kirimkan benda-benda utc yang tidak disadari (objek zaman). Zona waktu seharusnya hanya dihitung pada saat representasi di UI
nehem
1
Kedengarannya sudah cocok dengan pikiran Julien dengan cukup baik. Manakah dari rekomendasi spesifiknya (sebagaimana dirujuk di atas) yang menyesatkan?
Joe D'Andrea
10
Untuk menambahkan timezoneinformasi dalam Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)>>>print(d.tzinfo)'UTC+00:00'
Sejauh yang saya tahu dari docs.python.org/library/datetime.html , sebuah datetime tanpa tzinfo adalah satu di mana zona waktu tidak ditentukan. Berikut zona waktu telah ditentukan, sehingga secara logis harus hadir. Ada perbedaan besar antara tanggal / waktu tanpa zona waktu yang terkait dan yang pasti dalam UTC. (Idealnya mereka harus tipe IMO yang berbeda, tapi itu masalah lain ...)
Jon Skeet
@ JonSkeet Saya pikir Anda kehilangan titik Ignacio bahwa UTC bukan zona waktu. Luar biasa bahwa jawaban ini memiliki skor -9 saat saya mengetik ini ...
CS
3
@CS: Yah, Ignacio tidak pernah menyatakan bahwa ... dan walaupun secara tegas UTC bukan zona waktu, biasanya diperlakukan sebagai salah satu untuk membuat hidup lebih sederhana (termasuk dalam Python, misalnya dengan pytz.utc). Perhatikan bahwa ada perbedaan besar antara nilai yang offsetnya dari UTC tidak diketahui dan nilai di mana nilai itu dikenal sebagai 0. Yang terakhir adalah yang utcnow()harus dikembalikan, IMO. Itu akan cocok dengan "Objek sadar digunakan untuk mewakili momen tertentu dalam waktu yang tidak terbuka untuk interpretasi" sesuai dokumentasi.
Jawaban:
Itu berarti zona waktu itu naif, jadi Anda tidak bisa menggunakannya
datetime.astimezone
Anda bisa memberikan zona waktu seperti ini
sekarang Anda dapat mengubah zona waktu
Untuk mendapatkan waktu saat ini di zona waktu tertentu, Anda bisa mengirimkan tzinfo ke
datetime.now()
langsung:Ia bekerja untuk zona waktu apa pun termasuk yang mengamati daylight saving time (DST) yaitu, ia bekerja untuk zona waktu yang mungkin memiliki offset utc yang berbeda pada waktu yang berbeda (offset utc yang tidak tetap). Jangan gunakan
tz.localize(datetime.now())
- ini mungkin gagal selama transisi akhir-DST ketika waktu setempat ambigu.sumber
astimezone
. Jadi datetime tidak hanya tidak memiliki zona waktu asli, tetapi satu-satunya implementasi tzinfo yang tersedia secara luas adalah tidak sesuai dengan standar yang seharusnya.u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; gunakandatetime.now(tz)
saja.Perhatikan bahwa untuk Python 3.2 dan seterusnya,
datetime
modul berisidatetime.timezone
. Dokumentasi untukdatetime.utcnow()
mengatakan:Jadi kamu bisa melakukan:
sumber
datetime.now(timezone.utc)
ataudatetime.utcnow(timezone.utc)
?datetime.utcnow()
tidak membutuhkan argumen. Jadi harus begitudatetime.now(timezone.utc)
.datetime.now()
akan mengembalikan waktu mesin tetapidatetime.utcnow()
akan mengembalikan waktu UTC yang sebenarnya.datetime.utcnow()
tidak diseteltzinfo
untuk menunjukkan bahwa itu UTC. Tetapidatetime.now(datetime.timezone.utc)
mengembalikan waktu UTC dengantzinfo
set.tz
objek di konstruktor sekarang, ia akan mengembalikan waktu zona waktu itu? Baik! Terima kasih telah menunjukkan.Pustaka Python standar tidak menyertakan kelas tzinfo (tetapi lihat pep 431 ). Saya hanya bisa menebak alasannya. Secara pribadi saya pikir itu adalah kesalahan untuk tidak memasukkan kelas tzinfo untuk UTC, karena yang satu itu cukup tidak kontroversial untuk memiliki implementasi standar.
Sunting: Meskipun tidak ada implementasi di perpustakaan, ada satu yang diberikan sebagai contoh dalam
tzinfo
dokumentasi .Untuk menggunakannya, untuk mendapatkan waktu saat ini sebagai objek datetime sadar:
Ada
datetime.timezone.utc
dalam Python 3.2+:sumber
datetime
objek yang dibuat olehutcnow()
) ...timezone.utc
akhirnya telah ditambahkan ke Python 3.2. Untuk kompatibilitas mundur,utcnow()
masih mengembalikan objek waktu kurang zona, tetapi Anda bisa mendapatkan apa yang Anda inginkan dengan meneleponnow(timezone.utc)
.struct
modul akan melakukan konversi otomatis dari Unicode ke bytestring, dan keputusan terakhir adalah untuk memutus kompatibilitas dengan versi Python 3 sebelumnya untuk mencegah keputusan buruk dari maju.tzinfo
dokumentasi Python termasuk contoh kode untuk mengimplementasikannya, tetapi mereka tidak memasukkan fungsi itu dalam datetime itu sendiri! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutcpytz
adalah sumber yang bagus. Pada saat saya mengedit jawaban saya untuk dimasukkan ke dalam kode contoh, orang lain telah menyarankannya dan saya tidak ingin mencuri guntur mereka.The
pytz
Modul adalah salah satu pilihan, dan ada lagipython-dateutil
, yang meskipun juga paket pihak ketiga, mungkin sudah tersedia, tergantung pada dependensi lain dan sistem operasi.Saya hanya ingin memasukkan metodologi ini untuk referensi - jika Anda sudah menginstal
python-dateutil
untuk tujuan lain, Anda dapat menggunakannyatzinfo
daripada menduplikasipytz
Saya cenderung setuju bahwa panggilan
utcnow
harus mencakup informasi zona waktu UTC. Saya menduga bahwa ini tidak termasuk karena pustaka datetime bawaan default ke naet data untuk kompatibilitas lintas.sumber
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
itu selalu berhasil;datetime.now(dateutil.tz.tzlocal())
mungkin gagal selama transisi DST . PEP 495 - Disambiguasi Waktu Lokal dapat memperbaikidateutil
situasi di masa depan.utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(catatan:dateutil
dengan utc non-fixed offset (sepertidateutil.tz.tzlocal()
) mungkin gagal di sini , menggunakan sebuahpytz
solusi berbasis gantinya ).dateutil
untukdateutil.parser
, aku suka solusi ini yang terbaik. Itu yang sederhana seperti:utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Biola!!Julien Danjou menulis artikel bagus yang menjelaskan mengapa Anda tidak boleh berurusan dengan zona waktu . Kutipan:
Sayangnya, meskipun Anda dapat menggunakan
utcnow()
, Anda masih tidak akan melihat info zona waktu, seperti yang Anda temukan.Rekomendasi:
sumber
Untuk menambahkan
timezone
informasi dalam Python 3.2+sumber
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (default, 19 Jan 2017, 14:48:08)sumber
Tanggal UTC tidak memerlukan info zona waktu karena itu UTC, yang menurut definisi berarti mereka tidak memiliki offset.
sumber
pytz.utc
). Perhatikan bahwa ada perbedaan besar antara nilai yang offsetnya dari UTC tidak diketahui dan nilai di mana nilai itu dikenal sebagai 0. Yang terakhir adalah yangutcnow()
harus dikembalikan, IMO. Itu akan cocok dengan "Objek sadar digunakan untuk mewakili momen tertentu dalam waktu yang tidak terbuka untuk interpretasi" sesuai dokumentasi.