Apakah ada daftar Zona Waktu Pytz?

659

Saya ingin tahu apa semua nilai yang mungkin untuk argumen zona waktu di pytz perpustakaan Python. Bagaimana cara melakukannya?

ipegasus
sumber
6
Sangat lucu bagaimana "GMT", "GMT + 0", "GMT-0", "GMT0", "Greenwich", "UCT", "UTC", "Universal", dan "Zulu" pada dasarnya berarti hal yang sama dan namun ada begitu banyak entri untuk itu.
Joe Z.
43
GMT tidak sama dengan UTC. Itu kesalahan umum.
PawelRoman
1
@PawelRoman: GMT dapat berarti berbagai hal dalam konteks yang berbeda. Ini tidak berarti UTC kadang-kadang misalnya, sertifikat ssl waktu string seperti diterima membutuhkan GMT ( warisan). ssl.cert_time_to_second() ASN1_TIME_print()
jfs
3
@ PamelaRoman Anda benar dalam arti bahwa satu adalah zona waktu, dan yang lainnya adalah standar. Namun dalam arti praktis yang dipikirkan kebanyakan orang, keduanya merujuk pada saat yang sama.
merampok
1
@YongweiWu lihat stackoverflow.com/questions/11473721/…
Mark Ransom

Jawaban:

318

Anda dapat membuat daftar semua zona waktu yang tersedia dengan pytz.all_timezones:

In [40]: import pytz
In [41]: pytz.all_timezones
Out[42]: 
['Africa/Abidjan',
 'Africa/Accra',
 'Africa/Addis_Ababa',
 ...]

Ada juga pytz.common_timezones:

In [45]: len(pytz.common_timezones)
Out[45]: 403

In [46]: len(pytz.all_timezones)
Out[46]: 563
unutbu
sumber
9
Selain itu all_timezones, pytz juga menyediakan common_timezones .
Mark Hildreth
3
mengapa China hilang?
Adders
4
China menggunakan zona waktu tunggal , yang namanya zona waktu 'Asia/Shanghai'.
unutbu
1
Ungkapan ini menunjukkan hasil mengerikan yang dapat diberikan pytz: (datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('Asia/Shanghai')) - datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('UTC'))).total_seconds()(hasilnya bukan -28800). Saya akan menghindari pytz—dateutil.tz menyediakan fungsionalitas yang serupa tetapi menggunakan database zona waktu OS dan tidak memiliki masalah seperti itu.
Yongwei Wu
2
@YongweiWu ini adalah penggunaan API yang salah. Anda tidak boleh melewati zona waktu pytz dengan offset utc yang tidak tetap sebagai argumen tzinfo secara langsung. Gunakan metode .localize () seperti yang disarankan pytz docs.
jfs
38

Jangan buat daftar Anda sendiri - pytzmemiliki set bawaan:

import pytz
set(pytz.all_timezones_set)  
>>> {'Europe/Vienna', 'America/New_York', 'America/Argentina/Salta',..}

Anda kemudian dapat menerapkan zona waktu :

import datetime
tz = pytz.timezone('Pacific/Johnston')
ct = datetime.datetime.now(tz=tz)
>>> ct.isoformat()
2017-01-13T11:29:22.601991-05:00

Atau jika Anda sudah memiliki datetimeobjek yang sadar TZ (tidak naif):

# This timestamp is in UTC
my_ct = datetime.datetime.now(tz=pytz.UTC)

# Now convert it to another timezone
new_ct = my_ct.astimezone(tz)
>>> new_ct.isoformat()
2017-01-13T11:29:22.601991-05:00
anak-anak
sumber
27

Nama zona waktu adalah satu-satunya cara yang dapat diandalkan untuk menentukan zona waktu.

Anda dapat menemukan daftar nama zona waktu di sini: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones Perhatikan bahwa daftar ini berisi banyak nama alias, seperti AS / Timur untuk zona waktu yang benar-benar disebut Amerika / New_York.

Jika Anda secara terprogram ingin membuat daftar ini dari basis data zoneinfo, Anda dapat mengompilasinya dari file zone.tab di basis data zoneinfo. Saya tidak berpikir pytz memiliki API untuk mendapatkannya, dan saya juga tidak berpikir itu akan sangat berguna.

Lennart Regebro
sumber
14

Di sini, daftar kode negara Python, nama, benua, ibukota, dan zona waktu pytz.

countries = [
{'timezones': ['Europe/Paris'], 'code': 'FR', 'continent': 'Europe', 'name': 'France', 'capital': 'Paris'}
{'timezones': ['Africa/Kampala'], 'code': 'UG', 'continent': 'Africa', 'name': 'Uganda', 'capital': 'Kampala'},
{'timezones': ['Asia/Colombo'], 'code': 'LK', 'continent': 'Asia', 'name': 'Sri Lanka', 'capital': 'Sri Jayewardenepura Kotte'},
{'timezones': ['Asia/Riyadh'], 'code': 'SA', 'continent': 'Asia', 'name': 'Saudi Arabia', 'capital': 'Riyadh'},
{'timezones': ['Africa/Luanda'], 'code': 'AO', 'continent': 'Africa', 'name': 'Angola', 'capital': 'Luanda'},    
{'timezones': ['Europe/Vienna'], 'code': 'AT', 'continent': 'Europe', 'name': 'Austria', 'capital': 'Vienna'},
{'timezones': ['Asia/Calcutta'], 'code': 'IN', 'continent': 'Asia', 'name': 'India', 'capital': 'New Delhi'},
{'timezones': ['Asia/Dubai'], 'code': 'AE', 'continent': 'Asia', 'name': 'United Arab Emirates', 'capital': 'Abu Dhabi'},
{'timezones': ['Europe/London'], 'code': 'GB', 'continent': 'Europe', 'name': 'United Kingdom', 'capital': 'London'},
]

Untuk daftar lengkap: Gist Github

Semoga bermanfaat.

Jay Modi
sumber
4

Mereka tampaknya diisi oleh zona waktu basis data tz yang ditemukan di sini .

masukkan deskripsi gambar di sini

Chris Redford
sumber
1
pytzmenyediakan akses ke basis data tz (ini adalah sumber untuk data wikipedia).
jfs
4

EDIT: Saya akan sangat menghargainya jika Anda tidak mengundurkan diri jawaban ini lebih lanjut. Jawaban ini salah , tetapi saya lebih suka mempertahankannya sebagai catatan sejarah. Meskipun dapat diperdebatkan apakah antarmuka pytz rawan kesalahan, ia dapat melakukan hal-hal yang tidak dapat dilakukan dateutil.tz, terutama mengenai penghematan cahaya matahari di masa lalu atau di masa depan. Saya jujur ​​mencatat pengalaman saya dalam sebuah artikel "Zona waktu dengan Python" .


Jika Anda menggunakan platform seperti Unix, saya sarankan Anda menghindari pytz dan lihat saja di / usr / share / zoneinfo. dateutil.tz dapat memanfaatkan informasi di sana.

Sepotong kode berikut menunjukkan masalah yang dapat diberikan pytz. Saya terkejut ketika saya pertama kali mengetahuinya. (Cukup menarik, pytz yang diinstal oleh yum pada CentOS 7 tidak menunjukkan masalah ini.)

import pytz
import dateutil.tz
from datetime import datetime
print((datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('UTC')))
     .total_seconds())
print((datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.gettz('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.tzutc()))
     .total_seconds())

-29160.0
-28800.0

Yaitu zona waktu yang dibuat oleh pytz adalah untuk waktu lokal yang sebenarnya, bukan standar waktu setempat yang diamati orang. Shanghai sesuai dengan +0800, bukan +0806 seperti yang disarankan oleh pytz:

pytz.timezone('Asia/Shanghai')
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>

EDIT: Terima kasih atas komentar dan downvote Mark Ransom, sekarang saya tahu saya menggunakan pytz dengan cara yang salah. Singkatnya, Anda tidak seharusnya meneruskan hasil dari pytz.timezone(…)ke datetime, tetapi harus meneruskan datetimeke localizemetodenya.

Terlepas dari argumennya (dan kesalahan saya karena tidak membaca dokumentasi pytz lebih hati-hati), saya akan menyimpan jawaban ini. Saya menjawab pertanyaan dengan satu cara (bagaimana menghitung zona waktu yang didukung, meskipun tidak dengan pytz), karena saya percaya pytz tidak memberikan solusi yang benar. Meskipun kepercayaan saya salah, jawaban ini masih memberikan beberapa informasi, IMHO, yang berpotensi bermanfaat bagi orang yang tertarik pada pertanyaan ini. Cara Pytz yang benar dalam melakukan sesuatu adalah kontra-intuitif. Heck, jika tzinfo yang dibuat oleh pytz tidak boleh langsung digunakan datetime, itu harus tipe yang berbeda. Antarmuka pytz dirancang dengan buruk. Tautan yang diberikan oleh Mark menunjukkan bahwa banyak orang, bukan hanya saya, telah disesatkan oleh antarmuka pytz.

Yongwei Wu
sumber
2
Lihat stackoverflow.com/questions/11473721/… untuk perbaikannya. Tidak ada yang salah dengan itu pytz, Anda hanya salah menggunakannya. PS Ini bukan jawaban untuk pertanyaan sama sekali .
Mark Ransom
1
@MarkRansom Info bagus, dan senang mengetahuinya. Namun, saya tidak membeli argumen Anda. Antarmuka dirancang salah, titik. Ini sangat berlawanan dengan intuisi.
Yongwei Wu
3
Ya, antarmuka dirancang salah. Tapi itu datetimeantarmuka yang salah, bukan pytz. datetimetidak mengantisipasi objek zona waktu yang cerdas , sehingga antarmuka tidak menginisialisasi dengan benar.
Mark Ransom
1
Dengan hormat, saya tidak setuju. datetimeadalah bagian dari pustaka Python standar, dan itu adalah pytz yang harus mengikuti datetimeantarmuka, bukan sebaliknya. Jika ada yang bisa mengimplementasikan beberapa antarmuka dengan cara mereka berpikir lebih baik tanpa konsensus, tidak akan ada perangkat lunak yang kuat.
Yongwei Wu
2
Seperti yang saya katakan, pytztidak dapat mengikuti datetimeantarmuka karena datetimeantarmuka kurang. Para penulis antarmuka itu tidak mengantisipasi masalah zona waktu yang parameternya berubah selama bertahun-tahun. Hanya karena itu bagian dari distribusi Python standar tidak berarti itu sempurna.
Mark Ransom
-8

Menurut pendapat saya ini adalah cacat desain perpustakaan pytz. Seharusnya lebih dapat diandalkan untuk menentukan zona waktu menggunakan offset, misalnya

pytz.construct("UTC-07:00")

yang memberi Anda zona waktu Kanada / Pasifik.

Jinghui Niu
sumber
12
Offset berubah sepanjang tahun (biasanya karena waktu musim panas), jadi itu tidak sama dengan apa yang biasanya kita anggap sebagai zona waktu.
Ryan Hiebert
Sintaks yang dipilih didasarkan pada definisi dalam tzdata .
Brad Koch