Saya belum pernah mengonversi waktu ke dan dari UTC. Baru-baru ini ada permintaan agar aplikasi saya mengetahui zona waktu, dan saya telah menjalankan diri saya dalam lingkaran. Banyak informasi tentang mengonversi waktu lokal ke UTC, yang menurut saya cukup mendasar (mungkin saya juga melakukan hal yang salah), tetapi saya tidak dapat menemukan informasi tentang cara dengan mudah mengubah waktu UTC ke zona waktu pengguna akhir.
Singkatnya, dan aplikasi android mengirimkan saya (appengine app) data dan di dalam data itu ada cap waktu. Untuk menyimpan stempel waktu ke waktu utc yang saya gunakan:
datetime.utcfromtimestamp(timestamp)
Itu sepertinya berhasil. Ketika aplikasi saya menyimpan data, itu disimpan sebagai 5 jam ke depan (Saya EST -5)
Data sedang disimpan di BigTable appengine, dan ketika diambil keluar sebagai string seperti:
"2011-01-21 02:37:21"
Bagaimana cara mengubah string ini menjadi DateTime di zona waktu pengguna yang benar?
Juga, penyimpanan apa yang disarankan untuk informasi zona waktu pengguna? (Bagaimana Anda biasanya menyimpan info tz yaitu: "-5: 00" atau "EST" dll?) Saya yakin jawaban untuk pertanyaan pertama saya mungkin berisi parameter jawaban kedua.
Jawaban:
Jika Anda tidak ingin menyediakan objek Anda sendiri
tzinfo
, lihat pustaka python-dateutil . Ini memberikantzinfo
implementasi di atas database zoneinfo (Olson) sehingga Anda bisa merujuk ke aturan zona waktu dengan nama yang agak kanonik.Edit contoh yang diperluas untuk menunjukkan
strptime
penggunaanSunting 2 Memperbaiki penggunaan API untuk menunjukkan metode entri yang lebih baik
Sunting 3 Termasuk metode deteksi otomatis untuk zona waktu (Yarin)
sumber
dateutil.tz
dan menggunakantz.tzutc()
dantz.tzlocal()
sebagai objek zona waktu yang saya cari. Sepertinya basis data zona waktu pada sistem saya baik (saya check-in/usr/share/zoneinfo
). Tidak yakin apa yang terjadi.tz
modul adalah titik masuk yang benar untuk menggunakan untuk perpustakaan ini. Saya telah memperbarui jawaban saya untuk mencerminkan ini. Thedateutil.zoneinfo
modul I menunjukkan sebelumnya digunakan secara internal olehtz
modul sebagai kembali jatuh jika tidak dapat menemukan sistem zoneinfo DB. Jika Anda melihat ke dalam perpustakaan Anda akan melihat bahwa ada tarball DB zoneinfo dalam paket yang digunakannya jika tidak dapat menemukan DB sistem Anda. Contoh lama saya mencoba untuk memukul DB itu secara langsung dan saya kira Anda mengalami masalah saat memuat DB pribadi itu (bukankah pada jalur python?)dateutil
, gunakanpytz
saja .Berikut metode tangguh yang tidak bergantung pada pustaka eksternal apa pun:
Ini menghindari masalah waktu dalam contoh DelboyJay. Dan masalah waktu yang lebih rendah dalam amandemen Erik van Oosten.
Sebagai catatan kaki yang menarik, offset zona waktu yang dihitung di atas dapat berbeda dari ekspresi yang tampaknya setara berikut, mungkin karena perubahan aturan penghematan siang hari:
Pembaruan: Cuplikan ini memiliki kelemahan dalam menggunakan offset UTC saat ini, yang mungkin berbeda dari offset UTC pada waktu input. Lihat komentar pada jawaban ini untuk solusi lain.
Untuk menyiasati waktu yang berbeda, raih waktu dari waktu yang berlalu. Inilah yang saya lakukan:
sumber
pytz
-bukan db tidak mungkin, lihat PEP-431. Meskipun Anda dapat menulis solusi stdlib-only yang berfungsi dalam kasus seperti itu pada sistem yang sudah memiliki db zona waktu bersejarah misalnya, Linux, OS X, lihat jawaban saya .utc_datetime
itu.Lihat dokumentasi datetime pada objek tzinfo . Anda harus menerapkan zona waktu yang ingin Anda dukung sendiri. Ini adalah contoh di bagian bawah dokumentasi.
Berikut ini contoh sederhana:
Keluaran
sumber
replace
untuk mengatur zona waktu menjadi GMT dan menjadikannya zona waktu "sadar", lalu gunakanastimezone
untuk mengonversi zona waktu lain.Jika Anda ingin mendapatkan hasil yang benar bahkan untuk waktu yang sesuai dengan waktu lokal yang ambigu (misalnya, selama transisi DST) dan / atau offset utc lokal berbeda pada waktu yang berbeda di zona waktu lokal Anda, maka gunakan
pytz
zona waktu:sumber
Jawaban ini seharusnya membantu jika Anda tidak ingin menggunakan modul lain selain itu
datetime
.datetime.utcfromtimestamp(timestamp)
mengembalikandatetime
objek naif (bukan yang sadar). Orang yang sadar sadar akan zona waktu, dan naif tidak. Anda ingin yang sadar jika Anda ingin mengonversi antara zona waktu (mis. Antara UTC dan waktu lokal).Jika Anda bukan instantiating tanggal untuk memulai, tetapi Anda masih bisa membuat
datetime
objek naif dalam waktu UTC, Anda mungkin ingin mencoba kode Python 3.x ini untuk mengubahnya:Berhati-hatilah untuk tidak salah berasumsi bahwa jika zona waktu Anda saat ini MDT, penghematan siang hari tidak berfungsi dengan kode di atas karena ia mencetak MST. Anda akan perhatikan bahwa jika Anda mengubah bulan ke Agustus, itu akan mencetak MDT.
Cara mudah lain untuk mendapatkan
datetime
objek sadar (juga dalam Python 3.x) adalah membuatnya dengan zona waktu yang ditentukan untuk memulai. Berikut ini contohnya, menggunakan UTC:Jika Anda menggunakan Python 2.x, Anda mungkin harus subkelas
datetime.tzinfo
dan menggunakannya untuk membantu Anda membuatdatetime
objek sadar , karenadatetime.timezone
tidak ada di Python 2.x.sumber
Jika menggunakan Django, Anda dapat menggunakan
timezone.localtime
metode ini:sumber
Anda bisa menggunakan panah
Anda bisa memberi makan
arrow.get()
dengan apa saja. timestamp, string iso dllsumber
Secara tradisional saya menunda ini ke frontend - mengirim waktu dari backend sebagai cap waktu atau format waktu lainnya dalam UTC, kemudian membiarkan klien mengetahui offset zona waktu dan membuat data ini di zona waktu yang tepat.
Untuk webapp, ini cukup mudah dilakukan dalam javascript - Anda bisa mengetahui zona waktu peramban dengan cukup mudah menggunakan metode builtin dan kemudian membuat data dari backend dengan benar.
sumber
Anda dapat menggunakan
calendar.timegm
untuk mengonversi waktu Anda menjadi detik sejak zaman Unix dantime.localtime
untuk mengonversi kembali:Memberi
Fri Jan 21 05:37:21 2011
(karena saya di UTC + 03:00 zona waktu).sumber
misalnya, zona waktu saya adalah ' +08: 00 '. input utc = 2018-10-17T00: 00: 00.111Z , maka saya akan mendapatkan output = 2018-10-17T08: 00: 00 + 08: 00
sumber
Dari jawaban di sini , Anda dapat menggunakan modul waktu untuk mengonversi dari utc ke waktu lokal yang ditetapkan di komputer Anda:
sumber
Ini adalah versi cepat dan kotor yang menggunakan pengaturan sistem lokal untuk mengetahui perbedaan waktu. CATATAN: Ini tidak akan berfungsi jika Anda perlu mengonversi ke zona waktu tempat sistem Anda saat ini tidak berjalan. Saya telah menguji ini dengan pengaturan Inggris di bawah zona waktu BST
sumber
datetime.fromtimestamp(ts)
: posix timestamp (float seconds) -> objek datetime dalam waktu lokal (ini berfungsi baik jika OS mengingat offset utc masa lalu untuk zona waktu lokal yaitu, pada Unix tetapi tidak pada Windows untuk tanggal di masa lalu)). Kalau tidak, pytz bisa digunakan.offset = datetime.utcnow().replace(minute=0, second=0, microsecond=0) - datetime.now().replace(minute=0, second=0, microsecond=0)
Saya mendapat perbedaan mikrodetik aneh tanpa itu.datetime.fromtimestamp(ts)
alih-alih jawabannya?Menggabungkan jawaban dari franksand ke dalam metode yang nyaman.
sumber