Bevezetés
Az adatok különböző formákban jeleníthetők meg – a dátumok és időpontok kényelmes ábrázolásának módja húrok. Ahhoz azonban, hogy ezekkel a dátumokkal és időpontokkal aritmetikai módon dolgozhassunk (mint például az időeltérések kiszámítása, az idő hozzáadása vagy eltávolítása stb.) – át kell alakítanunk őket egy datetime
tárgy.
Az egyik leggyakoribb forrás a karakterlánc-formátumú dátumidő REST API-k, amelyek agnosztikus karakterláncokat adnak vissza, amelyeket aztán konvertálhatunk más formátumokba.
Ezenkívül – az időzónák gyakori fejfájást okoznak a dátumidő objektumokkal való munka során, ezért a konvertálás során is gondolnunk kell erre.
Ebben az útmutatóban megnézzük, hogyan lehet egy karakterlánc dátumot/időt a
datetime
objektum Pythonban, a beépített segítségéveldatetime
modul, hanem harmadik féltől származó modulok is, mint pldateutil
,arrow
és Maya, figyelembe véve az időzónákat.
Karakterláncok konvertálása datetime használatával
A dátum idő A modul három különböző objektumtípusból áll: date
, time
és datetime
Az date
az objektum tartalmazza a dátumot, time
tartja az időt, és datetime
dátumot és időt is tartalmaz!
import datetime
print(f'Current date/time: {datetime.datetime.now()}')
A kód futtatása a következőket eredményezné:
Current date/time: 2022-12-01 10:27:03.929149
Ha nincs megadva egyéni formázás, a rendszer az alapértelmezett karakterlánc-formátumot használja, azaz a „2022-12-01 10:27:03.929149” formátum ISO 8601 formátum (ÉÉÉÉ-HH-NNTHH:PP:SS.mmmmmm). Ha a bemeneti karakterláncunk létrehozásához a datetime
az objektum ugyanabban az ISO 8601 formátumban van, vagy ha előre tudja, hogy milyen formátumot fog kapni, könnyen elemezhetjük egy datetime
tárgy:
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)
Futtatása kinyomtatja a dátumot, az időt és a dátum-időt:
Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149
Itt használjuk a strptime()
módszer, amely két érvet fogad el:
- A karakterlánc-formátumú dátum
- Az első argumentum formátuma
A formátum ilyen megadása sokkal gyorsabbá teszi az elemzést, mivel datetime
nem kell önállóan próbálkoznia a formátum értelmezésével, ami számításilag sokkal drágább. A visszatérési érték a következő típusú datetime
.
A mi példánkban "2022-12-01 10:27:03.929149"
a bemeneti karakterlánc és "%Y-%m-%d %H:%M:%S.%f"
a dátum karakterláncunk formátuma. A visszatért datetime
értékét a rendszer tárolja date_time_obj
.
Mivel ez egy datetime
objektum, nevezhetjük a date()
és a time()
módszerek közvetlenül rajta. Amint a kimenetből látható, kiírja a bemeneti karakterlánc „dátum” és „idő” részét!
Formátum tokenek
Érdemes egy percet szánni a megértésre formátumú tokenek - A "%Y-%m-%d %H:%M:%S.%f"
ezelőttről.
Mindegyik token a dátum-idő különböző részét jelöli, mint például a nap, a hónap, az év, a hónap vagy a hét napja stb. támogatott tokenek listája elég kiterjedt ahhoz, hogy lehetővé tegye a különféle formázásokat. Néhány gyakran használt, amit korábban is használtunk:
%Y
: Év (4 számjegy)%m
: Hónap%d
: A hónap napja%H
: óra (24 óra)%M
: Percek%S
: Másodpercek%f
: Mikroszekundum
Jegyzet: Az év kivételével ezek a zsetonok várhatóan nullázottak (azaz augusztus a 8. hónap, és nullázva van 08
).
Az strptime() formátum tokenek használata a karakterlánc különböző dátum-idő formátummá alakításához
Ha egy karakterlánc formátuma ismert, könnyen értelmezhető a-ba datetime
objektum használatával strptime()
. Vessünk egy pillantást egy nem triviális példára, amely egyik formátumról a másikra fordítható:
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)
A beviteli karakterlánc egy formátumú volt – „17. július 2022. 9:20”. Ennek a formátumnak a ismeretében az alkotóelemeket leképeztük az ISO 8601 formátumra és átalakítottuk egy datetime
tárgy:
Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00
Íme egy rövid lista az általánosan használt karakterlánc-formátumú dátumokról és a hozzájuk tartozó formátumokról 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"
Bármilyen formátumú dátum-idő karakterláncot elemezhet – mindaddig, amíg a kapott bemenethez a megfelelő formátumjogkivonatokat használja.
Karakterlánc konvertálása dátum-idővé az időzónákkal
A dátum-idő kezelése bonyolultabbá válik az időzónák kezelésekor. Az összes fenti példa eddig naiv az időzónához képest. Ezek az úgynevezett naiv dátumidő objektumok.
Azonban a datetime
az objektumok pontosan tartalmaznak egy mezőt az időzónához kapcsolódó adatok tárolására – tzinfo
:
import datetime as dt
dtime = dt.datetime.now()
print(dtime)
print(dtime.tzinfo)
A tzinfo
mező célja, hogy a datetime.timezone
objektum, amely az időzóna információt jelöli. ez van None
alapértelmezés szerint, és azt jelzi, hogy a datetime objektum időzóna-naiv. Az időzónák kezelésére nagyon gyakori külső könyvtár pytz
. Beállíthatja PyTz tárgyakat, mint a tzinfo
mező is.
Ha még nincs meg, telepítse az alábbi módon:
$ pip install pytz
A PyTz használatával horgonyt hozhatunk létre az időzóna-tudatos dátumokhoz, például UTC:
import datetime as dt
import pytz
dtime = dt.datetime.now(pytz.utc)
print(dtime)
print(dtime.tzinfo)
output:
2022-12-01 02:07:41.960920+00:00
UTC
Már nem 11 óra van, hanem hajnali 2 óra, mert néhány órával korábban állítottuk be az időzónát! Ez megváltoztatja az időzónát a dátum és idő.
+00:00
a különbség a megjelenített idő és az UTC idő között, mint globális koordinációs horgony. Az időt UTC-re állítottuk be, tehát az eltolás az 00:00
. Ez egy időzóna-tudatos objektum.
Hasonlóképpen válthatjuk ugyanazt a dátumidő-értelmezést az időzónák között. Alakítsunk át egy karakterláncot, például „2022-06-29 17:08:00” dátum-idővé, majd lokalizálni az „Amerika/New_York” időzónához:
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)
Jegyzet: Honosítás az időzóna-naiv dátumidőt időzóna-tudatos dátumidővé változtatja, és az időzónát helyiként kezeli. Így a dátum és idő változatlan marad, de a különböző időzónák miatt már nem ugyanazt az időpontot jelenti, az időzónákhoz nem kötve.
Ugyanazt kapjuk dátum és idő érték, ellensúlyozza -04: 00 UTC időhöz képest:
2022-06-29 17:08:00-04:00
America/New_York
17:08 Tokióban nem ugyanabban az időpontban, mint 17:08-kor New Yorkban. 17:08 Tokióban és 3:08 New Yorkban.
Hogyan lehet megtalálni az összes időzóna kódot/álnevet?
Az összes elérhető időzóna megtalálásához ellenőrizze a all_timezones
mező, amely az összes elérhető időzóna listája:
print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
print(time_zone)
Tekintse meg gyakorlatias, gyakorlati útmutatónkat a Git tanulásához, amely tartalmazza a bevált gyakorlatokat, az iparág által elfogadott szabványokat és a mellékelt csalólapot. Hagyd abba a guglizást a Git parancsokkal, és valójában tanulni meg!
There are 594 timezones in PyTz
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...
Módosítsa a dátum és idő időzónáját
Átalakíthatjuk egy időzóna időzónáját datetime
objektumot egyik régióból a másikba, ahelyett, hogy egy időzóna-naiv dátumidőt lokalizálna egy időzóna lencséjén keresztül.
Ez különbözik a lokalizációtól, mivel a lokalizáció egy másik időpontot jelent, de egy objektum időzónájának konvertálása ugyanazt az időpontot ábrázolja, más lencsén keresztül:
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)
Először létrehoztunk egy datetime objektumot az aktuális idővel, és beállítottuk „Amerika/New_York” időzónának. Ezután a astimezone()
módszerrel, ezt konvertáltuk datetime
az „Európa/London” időzónához. Mindkét datetime
Az s különböző értékeket fog kiírni, az UTC-eltolást referenciaként használva közöttük:
America/New_York: 2022-11-30 21:24:30.123400-05:00
Europe/London: 2022-12-01 02:24:30.123400+00:00
2:24 másnap Londonban is ugyanabban az időpontban, mint előző nap 21:24-kor New Yorkban mivel London 5 órával előrébb van.
Ahogy az várható volt, a dátumok és időpontok eltérőek, mivel körülbelül 5 óra különbség van közöttük.
Karakterlánc konvertálása dátumidővé harmadik féltől származó könyvtárak használatával
Pythoné datetime
modul képes az összes különböző típusú karakterláncot a datetime
tárgy. De a fő probléma az, hogy ehhez létre kell hozni a megfelelő formázási kódot strptime()
képes megérteni. Ennek a karakterláncnak a létrehozása időt vesz igénybe, és megnehezíti a kód olvasását.
Ehelyett más, harmadik féltől származó könyvtárakat is használhatunk, hogy megkönnyítsük.
Egyes esetekben ezek a harmadik féltől származó könyvtárak jobb beépített támogatással is rendelkeznek a dátum-idő manipulálásához és összehasonlításához, sőt néhányban beépített időzónák is vannak, így nincs szükség további PyTz-csomag beépítésére.
Nézzünk meg néhány ilyen könyvtárat a következő szakaszokban.
Konvertálja a karakterláncot Datetime-re a dateutil segítségével
A dateutil modul kiterjesztése a datetime
modul. Egyik előnye, hogy nem kell értelmező kódot átadnunk egy karakterlánc elemzéséhez!
Karakterlánc automatikus konvertálása dátum-idővé formátumjogkivonat nélkül a Python segítségével dateutil
:
from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')
print(datetime)
Ezt parse
függvény automatikusan elemzi a karakterláncot! Nem kell megadnia semmilyen formátumú karakterláncot. Próbáljunk meg különböző típusú karakterláncokat elemezni a használatával 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')
output:
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
Látható, hogy szinte bármilyen típusú karakterlánc könnyen értelmezhető a dateutil
modult.
Bár ez kényelmes, emlékezzen a korábbiakra, hogy a formátum előrejelzése sokkal lassítja a kódot, így ha a kód nagy teljesítményt igényel, akkor lehet, hogy ez nem a megfelelő megközelítés az alkalmazás számára.
Konvertálja a karakterláncot Datetime-re Mayával
Maya emellett nagyon egyszerűvé teszi a karakterláncok elemzését és az időzónák megváltoztatását. Egy karakterlánc egyszerű konvertálása Python Mayával:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)
output:
2018-04-29
17:45:25
UTC
Az idő más időzónára való konvertálásához:
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)
output:
2018-04-29
13:45:25
America/New_York
Most nem olyan könnyű használni? Próbáljuk ki maya
ugyanazzal a karakterlánc-készlettel, amelyet mi is használtunk 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)
output:
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
Amint láthatja, az összes dátumformátum elemzése sikeresen megtörtént!
Ha nem adjuk meg az időzóna adatait, akkor automatikusan UTC-re konvertálja. Fontos tehát megjegyezni, hogy mi kell biztosítja a to_timezone
és a naive
paramétereket, ha az idő nem UTC-ben van.
Konvertálja a karakterláncot dátum-idővé a nyíl segítségével
nyíl egy másik könyvtár a dátumidő kezeléséhez Pythonban. És mint korábban vele maya
, a dátum és idő formátumát is automatikusan kitalálja. Az értelmezés után Pythont ad vissza datetime
tárgy a arrow
tárgy.
Egy karakterlánc egyszerű konvertálása dátum-idővé Python segítségével arrow
:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)
output:
2018-04-29
17:45:25
tzutc()
És itt van, hogyan használhatja arrow
az időzónák konvertálásához a to()
eljárás:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())
output:
2018-04-29T13:45:25-04:00
2018-04-29
13:45:25
Amint láthatja, a dátum-idő karakterlánc az „Amerika/New_York” régióra konvertálódik.
Most ismét használjuk ugyanazt a karakterlánc-készletet, amelyet fentebb használtunk:
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)
Ez a kód sikertelen lesz a megjegyzésben szereplő dátum-idő karakterláncoknál, ami a példáink több mint fele. A többi karakterlánc kimenete a következő lesz:
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
A megjegyzésben szereplő dátum-idő karakterláncok helyes elemzéséhez át kell adnia a megfelelőt formátumú tokenek hogy a könyvtár támpontokat adjon az elemzéséhez.
Következtetés
Ebben a cikkben különböző módokat mutattunk be egy karakterlánc a-ba történő elemzésére datetime
objektum Pythonban. Választhatja az alapértelmezett Pythont datetime
könyvtárat vagy az ebben a cikkben említett harmadik féltől származó könyvtárakat, sok más mellett.
A fő probléma az alapértelmezett datetime
csomag lényege, hogy szinte minden dátum-idő karakterlánc formátumhoz kézzel kell megadnunk az elemző kódot. Tehát, ha a karakterlánc formátuma a jövőben megváltozik, valószínűleg módosítania kell a kódot is. De sok harmadik féltől származó könyvtár, mint például az itt említettek, automatikusan kezeli.
Még egy probléma, amellyel szembesülünk, az időzónák kezelése. A kezelés legjobb módja az, ha az időt UTC formátumban tárolja az adatbázisában, majd szükség esetén konvertálja a felhasználó helyi időzónájába.
Ezek a könyvtárak nem csak a karakterláncok elemzésére alkalmasak, hanem számos különböző típusú dátum-időhöz kapcsolódó művelethez is használhatók. Azt javaslom, hogy nézze át a dokumentumokat, hogy részletesen megismerje a funkciókat.