Dizeleri Python'da tarih saatine dönüştürme

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 nesne datetime modülü, aynı zamanda üçüncü taraf modülleri gibi dateutil, 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 datetimes, 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.

Zaman Damgası:

Den fazla Yığın kötüye kullanımı