Merkkijonojen muuntaminen datetimeksi Pythonissa

esittely

Tiedot voidaan esittää eri muodoissa – ja kätevä tapa esittää päivämäärät ja kellonajat ovat jouset. Kuitenkin, jotta voimme käsitellä näitä päivämääriä ja aikoja aritmeettisesti (kuten aikaerojen laskeminen, ajan lisääminen tai poistaminen jne.) meidän on muutettava ne datetime esine.

Yksi yleisimmistä lähteistä merkkijonomuotoiset päivämäärä-ajat ovat REST-sovellusliittymiä, jotka palauttavat agnostisia merkkijonoja, jotka voimme sitten muuntaa muihin muotoihin.

Lisäksi aikavyöhykkeet ovat yleinen päänsärky käytettäessä datetime-objekteja, joten meidän on mietittävä sitä myös muuntamisen aikana.

Tässä oppaassa tarkastellaan, kuinka merkkijono päivämäärä/aika muunnetaan a datetime Pythonissa sisäänrakennetun objektin avulla datetime moduuli, mutta myös kolmannen osapuolen moduulit, kuten dateutil, arrow ja Maya, joka ottaa huomioon aikavyöhykkeet.

Merkkijonojen muuntaminen päivämäärä-ajan avulla

- treffiaika moduuli koostuu kolmesta eri objektityypistä: date, timeja datetime. date esine pitää päivämäärän, time pitää ajan, ja datetime pitää sekä päivämäärän että kellonajan!

import datetime
print(f'Current date/time: {datetime.datetime.now()}')

Tämän koodin suorittaminen johtaisi:

Current date/time: 2022-12-01 10:27:03.929149

Kun mukautettua muotoilua ei ole annettu, käytetään oletusmerkkijonomuotoa, eli muoto "2022-12-01 10:27:03.929149" on ISO 8601 muoto (VVVV-KK-PPTHH:MM:SS.mmmmmm). Jos syöttömerkkijonomme luodaan a datetime objekti on samassa ISO 8601 -muodossa tai jos tiedät vastaanottamasi muodon etukäteen, voimme jäsentää sen helposti datetime esine:

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)

Sen suorittaminen tulostaa päivämäärän, kellonajan ja päivämäärän ja kellonajan:

Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149

Tässä käytämme strptime() menetelmä, joka hyväksyy kaksi argumenttia:

  • Merkkijonomuotoinen päivämäärä
  • Ensimmäisen argumentin muoto

Muodon määrittäminen tällä tavalla tekee jäsentämisestä paljon nopeampaa, koska datetime ei tarvitse yrittää tulkita muotoa yksinään, mikä on laskennallisesti paljon kalliimpaa. Palautusarvo on tyyppiä datetime.

Esimerkissämme "2022-12-01 10:27:03.929149" on syötemerkkijono ja "%Y-%m-%d %H:%M:%S.%f" on päivämäärämerkkijonomme muoto. Palautettu datetime arvo tallennetaan muodossa date_time_obj.

Koska tämä on datetime objektia, voimme kutsua date() ja time() menetelmiä suoraan siihen. Kuten tulosteesta näkyy, se tulostaa syötemerkkijonon 'päivämäärä' ja 'aika'-osan!

Format Tokens

Kannattaa käyttää hetki ymmärtääkseni muotoisia tunnuksia - "%Y-%m-%d %H:%M:%S.%f" aikaisemmasta.

Jokainen merkki edustaa eri osaa päivämäärästä ja kellonajasta, kuten päivä, kuukausi, vuosi, kuukauden tai viikon päivä jne. luettelo tuetuista tunnuksista on riittävän laaja mahdollistamaan erilaisia ​​muotoiluja. Jotkut yleisesti käytetyistä, joita olemme myös käyttäneet aiemmin, ovat:

  • %Y: Vuosi (4 numeroa)
  • %m: Kuukausi
  • %d: Kuukauden päivä
  • %H: Tunti (24 tuntia)
  • %M: Pöytäkirja
  • %S: Sekuntia
  • %f: mikrosekuntia

Huomautus: Kaikkien näiden rahakkeiden, paitsi vuotta, odotetaan olevan nollapehmustettu (eli elokuu on 8. kuukausi, ja se on nollapehmustettu 08).

Strptime() Format Tokenien käyttäminen merkkijonon muuntamiseen eri päivämäärä-ajan muotoon

Jos merkkijonon muoto tunnetaan, se voidaan helposti jäsentää muotoon a datetime objektia käyttämällä strptime(). Katsotaanpa ei-triviaalia esimerkkiä, joka muuttuu muodosta toiseen:

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)

Syöttömerkkijono oli yhtä muotoa – "17 2022:9AM". Tietäen tämän muodon, kartoitimme osaelementit ISO 20 -muotoon ja muunsimme sen muotoon datetime esine:

Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00

Tässä on lyhyt luettelo yleisistä merkkijonomuotoisista päivämäärä-ajoista ja niitä vastaavista muodoista 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"

Voit jäsentää minkä tahansa muotoisen päivämäärä-aika-merkkijonon – kunhan käytät oikeaa muototunnusmerkkijonoa vastaanottamaasi syötteeseen.

Muunna merkkijono päivämääräksi aikavyöhykkeiden avulla

Päivämäärä-aikojen käsittelystä tulee monimutkaisempaa, kun käsitellään aikavyöhykkeitä. Kaikki yllä olevat esimerkit ovat toistaiseksi naiivia aikavyöhykkeelle. Nämä tunnetaan nimellä naiivit päivämäärä-aika-objektit.

Kuitenkin, datetime objektit sisältävät kentän tarkalleen aikavyöhykkeisiin liittyvien tietojen tallentamista varten – tzinfo:

import datetime as dt
dtime = dt.datetime.now()

print(dtime) 
print(dtime.tzinfo) 

- tzinfo kentän on tarkoitus olla a datetime.timezone objekti, joka tarkoittaa aikavyöhyketietoja. Sen None oletuksena ja osoittaa, että datetime-objekti on aikavyöhyke-naiivi. Hyvin yleinen ulkoinen kirjasto aikavyöhykkeiden käsittelyyn on pytz. Voit asettaa PyTz esineitä kuten tzinfo kenttä myös.

Jos sinulla ei vielä ole sitä - asenna se seuraavasti:

$ pip install pytz

PyTz:n avulla voimme luoda ankkurin aikavyöhyketietoisille päivämäärä-ajoille, kuten UTC:

import datetime as dt
import pytz

dtime = dt.datetime.now(pytz.utc)

print(dtime)
print(dtime.tzinfo)

lähtö:

2022-12-01 02:07:41.960920+00:00
UTC

Kello ei ole enää 11 vaan 2, koska aikavyöhyke on asetettu muutama tunti taaksepäin! Tämä muuttaa aikavyöhykettä päivämäärä-ajasta.

+00:00 on ero näytetyn ajan ja UTC-ajan välillä globaalina koordinaatioankkurina. Olemme asettaneet ajan UTC-ajaksi, joten siirtymä on 00:00. Tämä on aikavyöhyketietoinen objekti.

Vastaavasti voimme vaihtaa saman päivämäärä-ajan tulkintaa aikavyöhykkeiden välillä. Muunnetaan merkkijono, kuten "2022-06-29 17:08:00" päivämääräksi ja sen jälkeen paikallistaa se aikavyöhykkeelle "America/New_York":

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)

Huomautus: Localization muuntaa aikavyöhykkeelle ominaisen päivämäärä-ajan aikavyöhyketietoiseksi päivämäärä-aikaan ja käsittelee aikavyöhykettä paikallisena. Siten, päivämääräaika pysyy samana, mutta kun otetaan huomioon eri aikavyöhyke, se ei enää edusta samaa ajankohtaa, joka ei ole sidottu aikavyöhykkeisiin.

Me saamme saman päivämäärä-aika-arvo, kompensoi -04: 00 verrattuna UTC-aikaan:

2022-06-29 17:08:00-04:00
America/New_York

klo 17 Tokiossa ei ole samaan aikaan kuin 17 New Yorkissa. 17:08 Tokiossa on 3:08 New Yorkissa.

Kuinka löytää kaikki aikavyöhykekoodit/aliakset?

Löydät kaikki käytettävissä olevat aikavyöhykkeet tarkistamalla all_timezones -kenttä, joka on luettelo kaikista käytettävissä olevista aikavyöhykkeistä:

print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
   print(time_zone)

Tutustu käytännönläheiseen, käytännölliseen Gitin oppimisoppaaseemme, jossa on parhaat käytännöt, alan hyväksymät standardit ja mukana tuleva huijauslehti. Lopeta Git-komentojen googlailu ja oikeastaan oppia se!

There are 594 timezones in PyTz

Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...

Muuta päivämäärän aikavyöhykettä

Voimme muuntaa aikavyöhyketietoisen aikavyöhykkeen datetime objektin alueelta toiselle sen sijaan, että lokalisoitaisiin aikavyöhykkeellä naiivi päivämäärä-aika jonkin aikavyöhykkeen linssin kautta.

Tämä eroaa lokalisoinnista, koska lokalisointi edustaa erilaista ajankohtaa, mutta objektin aikavyöhykkeen muuntaminen edustaa samaa ajankohtaa eri linssin läpi:

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)

Ensin loimme yhden datetime-objektin nykyisellä kellonajalla ja asetimme sen aikavyöhykkeeksi "America/New_York". Sitten käyttämällä astimezone() menetelmällä, olemme muuntaneet tämän datetime aikavyöhykkeelle "Eurooppa/Lontoo". Molemmat datetimes tulostaa eri arvoja käyttämällä UTC-offsetia vertailulinkkinä niiden välillä:

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 seuraavana päivänä Lontoossa is sama ajankohta kuin 21 edellisenä päivänä New Yorkissa Lontoo on 5h edellä.

Kuten odotettua, päivämäärä-ajat ovat erilaisia, koska niiden välinen ero on noin 5 tuntia.

Muunna merkkijono päivämäärä-ajaksi käyttämällä kolmannen osapuolen kirjastoja

Pythonin datetime moduuli voi muuntaa kaikentyyppiset merkkijonot a datetime esine. Mutta suurin ongelma on, että tämän tekemiseksi sinun on luotava sopiva muotoilukoodimerkkijono strptime() voi ymmärtää. Tämän merkkijonon luominen vie aikaa ja tekee koodista vaikeamman lukea.

Sen sijaan voimme käyttää muita kolmansien osapuolien kirjastoja helpottaaksemme sitä.

Joissakin tapauksissa näissä kolmannen osapuolen kirjastoissa on myös parempi sisäänrakennettu tuki päivämäärä-aikojen manipulointiin ja vertailuun, ja joissakin on jopa sisäänrakennettuja aikavyöhykkeitä, joten sinun ei tarvitse sisällyttää ylimääräistä PyTz-pakettia.

Tarkastellaanpa joitain näistä kirjastoista seuraavissa osioissa.

Muunna merkkijono päivämääräksi dateutililla

- dateutil-moduuli on laajennus datetime moduuli. Yksi etu on, että meidän ei tarvitse välittää mitään jäsennyskoodia jäsentääksemme merkkijonoa!

Voit muuntaa merkkijonon automaattisesti päivämäärä-aikaan ilman muototunnusta Pythonin avulla dateutil:

from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')

print(datetime)

Tämä parse toiminto jäsentää merkkijonon automaattisesti! Sinun ei tarvitse sisällyttää muotomerkkijonoa. Yritetään jäsentää erityyppisiä merkkijonoja käyttämällä 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')

lähtö:

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

Voit nähdä, että melkein minkä tahansa tyyppisiä merkkijonoja voidaan jäsentää helposti käyttämällä dateutil moduuli.

Vaikka tämä on kätevää, muista aiemmin, että muodon ennustaminen hidastaa koodia paljon, joten jos koodi vaatii korkeaa suorituskykyä, tämä ei ehkä ole oikea lähestymistapa sovelluksellesi.

Muunna merkkijono päivämääräksi Mayan avulla

maya tekee myös erittäin helpoksi jäsentää merkkijonoa ja vaihtaa aikavyöhykettä. Voit muuntaa merkkijonon helposti Pythonin Mayalla:

import maya

dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)

lähtö:

2018-04-29
17:45:25
UTC

Ajan muuntaminen toiselle aikavyöhykkeelle:

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)

lähtö:

2018-04-29
13:45:25
America/New_York

Eikö se nyt ole helppokäyttöinen? Kokeillaan maya samoilla merkkijonoilla, joiden kanssa olemme käyttäneet 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)
    
    
    
    

lähtö:

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

Kuten näet, kaikki päivämäärämuodot jäsennettiin onnistuneesti!

Jos emme anna aikavyöhyketietoja, se muuntaa ne automaattisesti UTC:ksi. Joten on tärkeää huomata, että me täytyy tarjota to_timezone ja naive parametrit, jos aika ei ole UTC:ssä.

Muunna merkkijono päivämääräksi nuolella

nuoli on toinen kirjasto, joka käsittelee päivämäärä-aikaa Pythonissa. Ja kuten ennenkin maya, se myös selvittää päivämäärän ja kellonajan muodon automaattisesti. Kun se on tulkittu, se palauttaa Pythonin datetime objekti arrow esine.

Voit muuntaa merkkijonon helposti datetimeksi Pythonin avulla arrow:

import arrow

dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)

lähtö:

2018-04-29
17:45:25
tzutc()

Ja tässä on kuinka voit käyttää arrow muuntaaksesi aikavyöhykkeitä käyttämällä to() menetelmä:

import arrow

dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())

lähtö:

2018-04-29T13:45:25-04:00
2018-04-29
13:45:25

Kuten näet, päivämäärä-aika-merkkijono muunnetaan "Amerikka/New_York" -alueeksi.

Käytetään nyt taas samoja merkkijonoja, joita käytimme edellä:

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)
    
    
    
    

Tämä koodi epäonnistuu kommentoiduissa päivämäärä-aika-merkkijonoissa, mikä on yli puolet esimerkeistämme. Muiden merkkijonojen tulos on:

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

Jotta voit jäsentää oikein kommentoidut päivämäärä-aika-merkkijonot, sinun on välitettävä vastaava muotoisia tunnuksia antaa kirjastolle vihjeitä sen jäsentämiseen.

Yhteenveto

Tässä artikkelissa olemme näyttäneet erilaisia ​​tapoja jäsentää merkkijono muotoon a datetime objekti Pythonissa. Voit joko valita oletusarvoisen Pythonin datetime kirjasto tai jokin tässä artikkelissa mainituista kolmannen osapuolen kirjastoista monien muiden joukossa.

Suurin ongelma oletusasetuksen kanssa datetime paketti on, että meidän on määritettävä jäsennyskoodi manuaalisesti melkein kaikille päivämäärä-aika-merkkijonomuodoille. Joten jos merkkijonomuotosi muuttuu tulevaisuudessa, sinun on todennäköisesti muutettava myös koodia. Mutta monet kolmannen osapuolen kirjastot, kuten tässä mainitut, käsittelevät sen automaattisesti.

Toinen kohtaamamme ongelma on aikavyöhykkeiden käsitteleminen. Paras tapa käsitellä niitä on aina tallentaa aika tietokantaan UTC-muodossa ja muuntaa se sitten tarvittaessa käyttäjän paikalliseen aikavyöhykkeeseen.

Nämä kirjastot eivät sovellu vain merkkijonojen jäsentämiseen, vaan niitä voidaan käyttää moniin erilaisiin päivämäärään ja aikaan liittyviin toimintoihin. Suosittelen sinua käymään asiakirjat läpi oppiaksesi toiminnot yksityiskohtaisesti.

Aikaleima:

Lisää aiheesta Stackabus