Giriş
Veriler çeşitli biçimlerde temsil edilebilir ve tarihleri ve saatleri temsil etmenin uygun bir yolu dizeleri. Ancak, bu tarih ve saatlerle aritmetik bir şekilde çalışmak için (zaman farklarını hesaplamak, zaman eklemek veya çıkarmak vb.) datetime
nesne.
En yaygın kaynaklardan biri dize biçimli tarihler agnostik dizeler döndüren ve daha sonra diğer biçimlere dönüştürebileceğimiz REST API'leridir.
Ek olarak – tarih-zaman nesneleri ile çalışmak söz konusu olduğunda zaman dilimleri yaygın bir baş ağrısıdır, bu yüzden dönüştürürken bunu da düşünmemiz gerekecek.
Bu kılavuzda – bir dizi tarih/zamanın nasıl dönüştürüleceğine bir göz atacağız.
datetime
yerleşik kullanarak Python'da nesnedatetime
modülü, aynı zamanda üçüncü taraf modülleri gibidateutil
,arrow
ve Maya, saat dilimlerini hesaba katar.
Datetime Kullanarak Dizeleri Dönüştürme
The datetime modül üç farklı nesne türünden oluşur: date
, time
, ve datetime
. date
nesne tarihi tutar, time
zamanı tutar ve datetime
hem tarihi hem de saati tutar!
import datetime
print(f'Current date/time: {datetime.datetime.now()}')
Bu kodun çalıştırılması şunlarla sonuçlanır:
Current date/time: 2022-12-01 10:27:03.929149
Özel biçimlendirme verilmediğinde, varsayılan dizi biçimi kullanılır, yani "2022-12-01 10:27:03.929149" biçimi ISO 8601 biçim (YYYY-AA-GGTHS:AA:SS.aaaa). Girdi dizgimiz bir oluşturmak için ise datetime
nesne aynı ISO 8601 formatındadır veya önceden alacağınız formatı biliyorsanız, onu kolayca ayrıştırabiliriz. datetime
nesne:
import datetime
date_time_str = '2022-12-01 10:27:03.929149'
date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f')
print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)
Çalıştırıldığında tarih, saat ve tarih-saat yazdırılır:
Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149
Burada kullanıyoruz strptime()
iki bağımsız değişkeni kabul eden yöntem:
- Dize biçimli tarih
- İlk bağımsız değişkenin biçimi
Biçimin bu şekilde belirtilmesi, ayrıştırmayı çok daha hızlı hale getirir çünkü datetime
formatı kendi başına denemeye ve yorumlamaya gerek yoktur, bu hesaplama açısından çok daha pahalıdır. Dönen değer şu türdendir: datetime
.
Örneğimizde, "2022-12-01 10:27:03.929149"
giriş dizesidir ve "%Y-%m-%d %H:%M:%S.%f"
tarih dizimizin biçimidir. iade edilen datetime
değer olarak saklanır date_time_obj
.
Bu bir datetime
nesne olarak adlandırabiliriz. date()
ve time()
Yöntemler doğrudan bunun üzerindedir. Çıktıdan da görebileceğiniz gibi, giriş dizisinin 'tarih' ve 'saat' kısmını yazdırıyor!
Belirteçleri Biçimlendir
Anlamak için bir dakikanızı ayırmaya değer biçim belirteçleri - "%Y-%m-%d %H:%M:%S.%f"
önceden.
Her belirteç, tarih-zamanın gün, ay, yıl, ayın günü veya hafta gibi farklı bir bölümünü temsil eder. desteklenen belirteçlerin listesi çeşitli biçimlendirmeyi mümkün kılacak kadar kapsamlıdır. Daha önce de kullandığımız, yaygın olarak kullanılanlardan bazıları şunlardır:
%Y
: Yıl (4 hane)%m
: Ay%d
: Ayın günü%H
: Saat (24 saat)%M
: Dakika%S
: Saniye%f
: Mikrosaniye
Not: Yıl hariç tüm bu belirteçlerin sıfır dolgulu olması bekleniyor (yani Ağustos 8. aydır ve sıfır dolguludur) 08
).
Dizeyi Farklı Tarih-Saat Biçimine Dönüştürmek için strptime() Biçim Belirteçlerini Kullanma
Bir dizginin formatı biliniyorsa, kolayca bir diziye ayrıştırılabilir. datetime
kullanarak nesne strptime()
. Bir biçimden diğerine çeviren önemsiz olmayan bir örneğe bakalım:
import datetime
date_time_str = 'Jul 17 2022 9:20AM'
date_time_obj = datetime.datetime.strptime(date_time_str, '%b %d %Y %I:%M%p')
print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)
Giriş dizisi tek bir biçimdeydi - "17 Temmuz 2022 9:20". Bu formatı bilerek, kurucu unsurları ISO 8601 formatına eşledik ve onu bir formata dönüştürdük. datetime
nesne:
Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00
Aşağıda, ortak dize biçimli tarih saatlerinin ve bunlara karşılık gelen biçimlerin kısa bir listesi bulunmaktadır. strptime()
:
"Jun 28 2018 at 7:40AM" -> "%b %d %Y at %I:%M%p"
"September 18, 2017, 22:19:55" -> "%B %d, %Y, %H:%M:%S"
"Sun,05/12/99,12:30PM" -> "%a,%d/%m/%y,%I:%M%p"
"Mon, 21 March, 2015" -> "%a, %d %B, %Y"
"2018-03-12T10:12:45Z" -> "%Y-%m-%dT%H:%M:%SZ"
Aldığınız giriş için doğru biçim belirteçleri dizisini kullandığınız sürece, herhangi bir biçimdeki bir tarih-saat dizesini ayrıştırabilirsiniz.
Dizeyi Saat Dilimleriyle Datetime'a Dönüştürün
Saat dilimleriyle uğraşırken tarih-saatleri işlemek daha karmaşık hale gelir. Şimdiye kadar yukarıdaki tüm örnekler, zaman dilimi için saftır. Bunlar olarak bilinir saf tarih saat nesneleri.
Bununla birlikte, datetime
nesneler, tam olarak saat dilimiyle ilgili verileri depolamak için bir alan içerir – tzinfo
:
import datetime as dt
dtime = dt.datetime.now()
print(dtime)
print(dtime.tzinfo)
The tzinfo
alan şu anlama gelir: datetime.timezone
saat dilimi bilgisini gösteren nesne. Onun None
varsayılan olarak, ve datetime nesnesinin saat diliminde saf olduğunu belirtir. Saat dilimlerini işlemek için çok yaygın bir harici kitaplık pytz
. Ayarlayabilirsiniz PyTz olarak nesneler tzinfo
alan da.
Zaten sahip değilseniz – şununla kurun:
$ pip install pytz
PyTz'yi kullanarak, UTC gibi saat dilimine duyarlı tarih ve saatler için bir çapa oluşturabiliriz:
import datetime as dt
import pytz
dtime = dt.datetime.now(pytz.utc)
print(dtime)
print(dtime.tzinfo)
Çıktı:
2022-12-01 02:07:41.960920+00:00
UTC
Saat dilimini birkaç saat geri aldığımız için saat artık 11:2 değil, XNUMX:XNUMX! Bu saat dilimini değiştirir tarih saatinin.
+00:00
görüntülenen saat ile küresel koordinasyon çapası olarak UTC saati arasındaki farktır. Saati UTC olarak ayarladık, yani ofset 00:00
. Bu bir saat dilimine duyarlı nesne.
Benzer şekilde, aynı tarih saatin yorumunu saat dilimleri arasında değiştirebiliriz. “2022-06-29 17:08:00” gibi bir diziyi tarih saatine dönüştürelim ve sonra yerelleştirmek “America/New_York” saat dilimine göre:
import datetime as dt
import pytz
date_time_str = '2022-06-29 17:08:00'
date_time_obj = dt.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
timezone = pytz.timezone('America/New_York')
timezone_date_time_obj = timezone.localize(date_time_obj)
print(timezone_date_time_obj)
print(timezone_date_time_obj.tzinfo)
Not: Yerelleştirme zaman diliminden habersiz bir tarih saatini saat diliminden haberdar bir tarih saatine dönüştürür ve saat dilimini yerel saat dilimi olarak ele alır. Böylece tarih saat aynı kalır, ancak farklı saat dilimi göz önüne alındığında, artık saat dilimlerinden bağımsız olarak aynı zaman noktasını temsil etmez.
aynısını alıyoruz tarih saat değeri, ofset -04: 00 UTC saatine kıyasla:
2022-06-29 17:08:00-04:00
America/New_York
Tokyo'da 17:08 değil New York'ta 17:08 ile aynı zaman noktası. Tokyo'da 17:08, New York'ta 3:08'dir.
Tüm saat dilimi kodlarını/takma adlarını nasıl bulabilirim?
Kullanılabilir tüm saat dilimlerini bulmak için all_timezones
kullanılabilir tüm saat dilimlerinin bir listesi olan alan:
print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
print(time_zone)
En iyi uygulamalar, endüstri tarafından kabul edilen standartlar ve dahil edilen hile sayfası ile Git'i öğrenmek için uygulamalı, pratik kılavuzumuza göz atın. Googling Git komutlarını durdurun ve aslında öğrenmek o!
There are 594 timezones in PyTz
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...
Datetime'ın Saat Dilimini Değiştirin
Saat dilimini tanıyan bir saat dilimini dönüştürebiliriz datetime
bir zaman dilimi merceğinden saf bir tarih saatini yerelleştirmek yerine, bir bölgeden diğerine nesne.
Bu, yerelleştirmeden farklıdır, çünkü yerelleştirme zaman içinde farklı bir noktayı temsil eder, ancak bir nesnenin saat dilimini dönüştürmek farklı bir mercek aracılığıyla zaman içinde aynı noktayı temsil eder:
import datetime as dt
import pytz
timezone_nw = pytz.timezone('America/New_York')
nw_datetime_obj = dt.datetime.now(timezone_nw)
timezone_london = pytz.timezone('Europe/London')
london_datetime_obj = nw_datetime_obj.astimezone(timezone_london)
print('America/New_York:', nw_datetime_obj)
print('Europe/London:', london_datetime_obj)
İlk olarak, geçerli saate sahip bir tarih saat nesnesi oluşturduk ve bunu "Amerika/New_York" saat dilimi olarak ayarladık. Daha sonra kullanarak astimezone()
yöntemi, bunu dönüştürdük datetime
“Avrupa/Londra” saat dilimine. İkisi birden datetime
s, aralarında bir referans bağlantısı olarak UTC ofsetini kullanarak farklı değerler yazdıracaktır:
America/New_York: 2022-11-30 21:24:30.123400-05:00
Europe/London: 2022-12-01 02:24:30.123400+00:00
Ertesi gün Londra'da 2:24 is New York'ta önceki gün 21:24 ile aynı zaman noktası çünkü Londra 5 saat ileridedir.
Beklendiği gibi, tarih-saatler yaklaşık 5 saat arayla olduğundan farklıdır.
Üçüncü Taraf Kitaplıklarını Kullanarak Dizeyi Tarih Saatine Dönüştürün
Python'un datetime
modül, tüm farklı dizi türlerini bir diziye dönüştürebilir. datetime
nesne. Ancak asıl sorun, bunu yapmak için uygun biçimlendirme kod dizesini oluşturmanız gerektiğidir. strptime()
anlayabilmek. Bu dizeyi oluşturmak zaman alır ve kodun okunmasını zorlaştırır.
Bunun yerine, bunu kolaylaştırmak için diğer üçüncü taraf kitaplıklarını kullanabiliriz.
Bazı durumlarda, bu üçüncü taraf kitaplıkları, tarih-saatleri değiştirmek ve karşılaştırmak için daha iyi yerleşik desteğe sahiptir ve hatta bazılarında yerleşik saat dilimleri vardır, bu nedenle fazladan bir PyTz paketi eklemenize gerek yoktur.
Aşağıdaki bölümlerde bu kitaplıklardan birkaçına göz atalım.
Dizeyi dateutil ile Datetime'a dönüştürün
The tarih modülü bir uzantısıdır datetime
modül. Bir avantaj, bir diziyi ayrıştırmak için herhangi bir ayrıştırma kodu geçirmemize gerek olmamasıdır!
Python'u kullanarak bir dizgiyi biçim belirteci olmadan otomatik olarak tarih saatine dönüştürmek için dateutil
:
from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')
print(datetime)
Bu parse
işlev dizeyi otomatik olarak ayrıştırır! Herhangi bir biçim dizesi eklemeniz gerekmez. Kullanarak farklı türde dizileri ayrıştırmaya çalışalım. dateutil
:
from dateutil.parser import parse
date_array = [
'2018-06-29 08:15:27.243860',
'Jun 28 2018 7:40AM',
'Jun 28 2018 at 7:40AM',
'September 18, 2017, 22:19:55',
'Sun, 05/12/1999, 12:30PM',
'Mon, 21 March, 2015',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
'Tuesday , 6th September, 2017 at 4:30pm'
]
for date in date_array:
print('Parsing: ' + date)
dt = parse(date)
print(dt.date())
print(dt.time())
print(dt.tzinfo)
print('n')
Çıktı:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29
08:15:27.243860
None
Parsing: Jun 28 2018 7:40AM
2018-06-28
07:40:00
None
Parsing: Jun 28 2018 at 7:40AM
2018-06-28
07:40:00
None
Parsing: September 18, 2017, 22:19:55
2017-09-18
22:19:55
None
Parsing: Sun, 05/12/1999, 12:30PM
1999-05-12
12:30:00
None
Parsing: Mon, 21 March, 2015
2015-03-21
00:00:00
None
Parsing: 2018-03-12T10:12:45Z
2018-03-12
10:12:45
tzutc()
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29
17:08:00.586525
tzutc()
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29
17:08:00.586525
tzoffset(None, 18000)
Parsing: Tuesday , 6th September, 2017 at 4:30pm
2017-09-06
16:30:00
None
Hemen hemen her tür dizgenin kullanılarak kolayca ayrıştırılabileceğini görebilirsiniz. dateutil
modülü.
Bu uygun olsa da, biçimi tahmin etmek zorunda olmanın kodu çok daha yavaş hale getirdiğini daha önce hatırlayın, bu nedenle kodunuz yüksek performans gerektiriyorsa, bu uygulamanız için doğru yaklaşım olmayabilir.
Maya ile String'i Datetime'a Dönüştürün
Maya ayrıca bir dizeyi ayrıştırmayı ve saat dilimlerini değiştirmeyi çok kolaylaştırır. Bir diziyi Python'un Maya'sıyla kolayca dönüştürmek için:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Çıktı:
2018-04-29
17:45:25
UTC
Saati farklı bir saat dilimine dönüştürmek için:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime(to_timezone='America/New_York', naive=False)
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Çıktı:
2018-04-29
13:45:25
America/New_York
Şimdi kullanımı o kadar kolay değil mi? hadi deneyelim maya
kullandığımız aynı dizi dizileriyle dateutil
:
import maya
date_array = [
'2018-06-29 08:15:27.243860',
'Jun 28 2018 7:40AM',
'Jun 28 2018 at 7:40AM',
'September 18, 2017, 22:19:55',
'Sun, 05/12/1999, 12:30PM',
'Mon, 21 March, 2015',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
'Tuesday , 6th September, 2017 at 4:30pm'
]
for date in date_array:
print('Parsing: ' + date)
dt = maya.parse(date).datetime()
print(dt)
Çıktı:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29 08:15:27.243860+00:00
Parsing: Jun 28 2018 7:40AM
2018-06-28 07:40:00+00:00
Parsing: Jun 28 2018 at 7:40AM
2018-06-28 07:40:00+00:00
Parsing: September 18, 2017, 22:19:55
2017-09-18 22:19:55+00:00
Parsing: Sun, 05/12/1999, 12:30PM
1999-05-12 12:30:00+00:00
Parsing: Mon, 21 March, 2015
2015-03-21 00:00:00+00:00
Parsing: 2018-03-12T10:12:45Z
2018-03-12 10:12:45+00:00
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29 17:08:00.586525+00:00
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29 12:08:00.586525+00:00
Parsing: Tuesday , 6th September, 2017 at 4:30pm
2017-09-06 16:30:00+00:00
Gördüğünüz gibi, tüm tarih biçimleri başarıyla ayrıştırıldı!
Zaman dilimi bilgisini sağlamazsak, otomatik olarak UTC'ye dönüştürür. Bu nedenle, biz not etmek önemlidir şart sağlamak to_timezone
ve naive
zaman UTC'de değilse parametreler.
Dizeyi Okla Tarih Saatine Dönüştür
Ok Python'da tarih saatiyle ilgilenmek için başka bir kitaplıktır. ve daha önce olduğu gibi maya
, aynı zamanda tarih saat biçimini de otomatik olarak hesaplar. Yorumlandıktan sonra bir Python döndürür datetime
nesneden arrow
nesne.
Python'u kullanarak bir dizeyi tarih saatine kolayca dönüştürmek için arrow
:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Çıktı:
2018-04-29
17:45:25
tzutc()
Ve işte nasıl kullanabileceğiniz arrow
kullanarak saat dilimlerini dönüştürmek için to()
yöntem:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())
Çıktı:
2018-04-29T13:45:25-04:00
2018-04-29
13:45:25
Gördüğünüz gibi tarih-saat dizisi “Amerika/New_York” bölgesine dönüştürülmüştür.
Şimdi, yukarıda kullandığımız aynı dizi dizisini tekrar kullanalım:
import arrow
date_array = [
'2018-06-29 08:15:27.243860',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
]
for date in date_array:
dt = arrow.get(date)
print('Parsing: ' + date)
print(dt)
Bu kod, örneklerimizin yarısından fazlası olan yorumlanan tarih-saat dizeleri için başarısız olacaktır. Diğer dizelerin çıktısı şöyle olacaktır:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29T08:15:27.243860+00:00
Parsing: 2018-03-12T10:12:45Z
2018-03-12T10:12:45+00:00
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29T17:08:00.586525+00:00
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29T17:08:00.586525+05:00
Yorumlanan tarih-saat dizelerini doğru bir şekilde ayrıştırmak için, karşılık gelenleri iletmeniz gerekir. biçim belirteçleri kütüphaneye nasıl ayrıştırılacağına dair ipuçları vermek.
Sonuç
Bu makalede, bir dizeyi bir diziye ayrıştırmanın farklı yollarını gösterdik. datetime
Python'da nesne. Varsayılan Python'u seçebilirsiniz. datetime
kitaplığı veya bu makalede bahsedilen üçüncü taraf kitaplıklardan herhangi biri ve diğerleri.
Varsayılan ile ana sorun datetime
paket, neredeyse tüm tarih-zaman dizgi biçimleri için ayrıştırma kodunu manuel olarak belirtmemiz gerektiğidir. Bu nedenle, dize biçiminiz gelecekte değişirse, büyük olasılıkla kodunuzu da değiştirmeniz gerekecektir. Ancak burada belirtilenler gibi birçok üçüncü taraf kitaplığı bunu otomatik olarak halleder.
Karşılaştığımız bir başka sorun da zaman dilimleriyle uğraşmaktır. Bunları işlemenin en iyi yolu, her zaman veritabanınızdaki zamanı UTC biçiminde depolamak ve ardından gerektiğinde kullanıcının yerel saat dilimine dönüştürmektir.
Bu kitaplıklar yalnızca dizeleri ayrıştırmak için iyi değildir, aynı zamanda tarih-zamanla ilgili birçok farklı türde işlem için kullanılabilirler. İşlevleri ayrıntılı olarak öğrenmek için belgeleri gözden geçirmenizi tavsiye ederim.