Stringide teisendamine Pythonis kuupäevakellaks

Sissejuhatus

Andmeid saab esitada mitmel erineval kujul – see on mugav viis kuupäevade ja kellaaegade esitamiseks stringid. Kuid nende kuupäevade ja kellaaegadega aritmeetiliseks töötamiseks (näiteks ajavahe arvutamiseks, aja lisamiseks või eemaldamiseks jne) peame need teisendama datetime objekt

Üks levinumaid allikaid stringi vormingus kuupäeva ja kellaajad on REST API-d, mis tagastavad agnostilisi stringe, mida saame seejärel teisendada muudesse vormingutesse.

Lisaks valmistavad ajavööndid kuupäeva-aja objektidega töötamisel sageli peavalu, nii et peame ka teisendamisel sellele mõtlema.

Selles juhendis vaatleme, kuidas teisendada stringi kuupäev/kellaaeg a-ks datetime objekt Pythonis, kasutades sisseehitatud datetime moodul, aga ka kolmandate osapoolte moodulid nagu dateutil, arrow ja Maya, võttes arvesse ajavööndeid.

Stringide teisendamine kuupäeva ja kellaaja abil

. kuupäev Kellaaeg moodul koosneb kolmest erinevast objektitüübist: date, timeja datetime. date objektil on kuupäev, time hoiab aega ja datetime hoiab nii kuupäeva kui kellaaega!

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

Selle koodi käivitamine tooks kaasa:

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

Kui kohandatud vormingut pole antud, kasutatakse stringi vaikevormingut, st vorming "2022-12-01 10:27:03.929149" on ISO 8601 formaat (AAAA-KK-PPTTH:MM:SS.mmmmmm). Kui meie sisendstring luuakse a datetime objekt on samas ISO 8601 vormingus või kui teate vormingut, mille saate eelnevalt, saame selle hõlpsasti sõeluda datetime objekt:

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)

Selle käivitamisel prinditakse kuupäev, kellaaeg ja kuupäev-kellaaeg:

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

Siin kasutame strptime() meetod, mis aktsepteerib kahte argumenti:

  • Stringi vormingus kuupäev
  • Esimese argumendi vorming

Sellise vormingu määramine muudab sõelumise palju kiiremaks datetime ei pea proovima vormingut iseseisvalt tõlgendada, mis on arvutuslikult palju kallim. Tagastusväärtus on tüüpi datetime.

Meie näites "2022-12-01 10:27:03.929149" on sisendstring ja "%Y-%m-%d %H:%M:%S.%f" on meie kuupäevastringi vorming. Tagastatud datetime väärtus salvestatakse kui date_time_obj.

Kuna see on a datetime objekti, võime nimetada date() ja time() meetodid otse sellel. Nagu väljundist näete, prindib see sisendstringi osa "kuupäev" ja "kellaaeg"!

Vorminda märgid

Mõistmiseks tasub võtta hetk vormingu märgid - "%Y-%m-%d %H:%M:%S.%f" varasemast.

Iga märk tähistab kuupäeva ja kellaaja erinevat osa, nagu päev, kuu, aasta, kuu või nädala päev jne. toetatud žetoonide loend on piisavalt ulatuslik, et võimaldada erinevaid vorminguid. Mõned sagedamini kasutatavad, mida oleme ka varem kasutanud, on järgmised:

  • %Y: aasta (4 numbrit)
  • %m: Kuu
  • %d: Kuu päev
  • %H: tund (24 tundi)
  • %M: Minutid
  • %S: Sekundid
  • %f: mikrosekundeid

Märge: Kõik need märgid, välja arvatud aasta, peavad olema nullpolsterdatud (st august on 8. kuu ja nulliga 08).

Strptime() Format Tokenite kasutamine stringi teisendamiseks erinevasse kuupäeva ja kellaaja vormingusse

Kui stringi vorming on teada, saab selle hõlpsasti sõeluda a-ks datetime objekti kasutamine strptime(). Vaatame mittetriviaalset näidet, mis tõlgib ühest vormingust teise:

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)

Sisendstring oli ühes vormingus – “Jul 17 2022 9:20AM”. Teades seda vormingut, vastendasime koostisosad ISO 8601 vormingusse ja teisendasime selle datetime objekt:

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

Siin on lühike loend tavalistest stringivormingus kuupäevaaegadest ja nende vastavatest vormingutest 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"

Saate sõeluda mis tahes vormingus kuupäeva ja kellaaja stringi – seni, kuni kasutate saadava sisendi jaoks õiget vormingumärkide stringi.

Teisendage string ajavööndite abil kuupäevaks kuupäevaks

Kuupäevade ja kellaaegade käsitlemine muutub ajavööndite käsitlemisel keerulisemaks. Kõik ülaltoodud näited on seni ajavööndi suhtes naiivsed. Need on tuntud kui naiivsed kuupäeva-aja objektid.

Kuid datetime objektid sisaldavad välja täpselt ajavööndiga seotud andmete salvestamiseks – tzinfo:

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

print(dtime) 
print(dtime.tzinfo) 

. tzinfo väli on mõeldud a datetime.timezone objekt, mis tähistab ajavööndi teavet. See on None vaikimisi ja tähistab, et datetime objekt on ajavööndi suhtes naiivne. Väga levinud väline teek ajavööndite käsitlemiseks on pytz. Saate määrata PyTz objektid nagu tzinfo ka väli.

Kui teil seda veel pole, installige see järgmiselt:

$ pip install pytz

PyTz abil saame luua ankru ajavööndist lähtuvate kuupäevade jaoks, näiteks UTC:

import datetime as dt
import pytz

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

print(dtime)
print(dtime.tzinfo)

Väljund:

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

Kell ei ole enam 11:2, vaid XNUMX:XNUMX, sest oleme määranud ajavööndi paar tundi tagasi! See muudab ajavööndit kuupäeva ja kellaaja kohta.

+00:00 on globaalse koordinatsiooniankruna kuvatava aja ja UTC-aja erinevus. Oleme määranud kellaaja UTC-s, seega on nihe 00:00. See on ajavööndist teadlik objekt.

Samamoodi saame ajavööndite vahel vahetada sama kuupäeva ja kellaaja tõlgendust. Teisendame stringi, näiteks „2022-06-29 17:08:00” kuupäevaks ja kellaajaks ja seejärel lokaliseerida see ajavööndisse "Ameerika/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)

Märge: lokaliseerimine muudab ajavööndi suhtes naiivse kuupäeva-kellaaja ajavööndipõhiseks kuupäevakellaks ja käsitleb ajavööndit kohalikuna. Seega, kuupäev ja kellaaeg jääb samaks, kuid erinevat ajavööndit arvestades ei tähista see enam sama ajahetke, mis on ajavöönditega sidumata.

Me saame sama datetime väärtus, kompenseerib -04: 00 võrreldes UTC ajaga:

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

17:08 Tokyos ei ole sama ajahetk kui 17:08 New Yorgis. 17:08 Tokyos on 3:08 New Yorgis.

Kuidas leida kõiki ajavööndi koode/aliaseid?

Kõigi saadaolevate ajavööndite leidmiseks vaadake üle all_timezones väli, mis on kõigi saadaolevate ajavööndite loend:

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

Tutvuge meie praktilise ja praktilise Giti õppimise juhendiga, mis sisaldab parimaid tavasid, tööstusharus aktsepteeritud standardeid ja kaasas olevat petulehte. Lõpetage Giti käskude guugeldamine ja tegelikult õppima seda!

There are 594 timezones in PyTz

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

Muutke kuupäeva ja kellaaja ajavööndit

Saame teisendada ajavööndi ajavöönditundlikuks datetime objekti ühest piirkonnast teise, selle asemel, et lokaliseerida ajavööndist naiivset kuupäeva-kellaaja läbi mõne ajavööndi objektiivi.

See erineb lokaliseerimisest, kuna lokaliseerimine tähistab erinevat ajahetke, kuid objekti ajavööndi teisendamine tähistab sama ajahetke läbi erineva objektiivi:

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)

Esiteks lõime ühe kuupäeva-aja objekti praeguse kellaajaga ja määrasime selle ajavööndiks “Ameerika/New_York”. Seejärel kasutades astimezone() meetod, oleme selle teisendanud datetime ajavööndisse “Euroopa/London”. Mõlemad datetimes prindib erinevad väärtused, kasutades UTC nihet nendevahelise võrdluslülina:

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 järgmisel päeval Londonis is sama ajahetkega kui 21:24 eelmisel päeval New Yorgis kuna London on 5h ees.

Ootuspäraselt on kuupäevad erinevad, kuna nende vahe on umbes 5 tundi.

Teisendage string kuupäevaks kolmanda osapoole raamatukogude abil

Pythoni oma datetime moodul saab teisendada kõik erinevat tüüpi stringid a-ks datetime objektiks. Kuid peamine probleem on see, et selleks peate looma sobiva vormingu koodistringi, mis strptime() saab aru. Selle stringi loomine võtab aega ja muudab koodi lugemise raskemaks.

Selle asemel saame selle hõlbustamiseks kasutada muid kolmandate osapoolte teeke.

Mõnel juhul on neil kolmandate osapoolte teekidel ka parem sisseehitatud tugi kuupäevade ja kellaaegade manipuleerimiseks ja võrdlemiseks ning mõnel on isegi sisseehitatud ajavööndid, nii et te ei pea lisama täiendavat PyTz-paketti.

Vaatame mõnda neist teekidest järgmistes jaotistes.

Teisendage string kuupäevaks kuupäevaks kuupäevaga dateutil

. dateutil moodul on laiendus datetime moodul. Üks eelis on see, et me ei pea stringi sõelumiseks parsimiskoodi edastama!

Stringi automaatseks teisendamiseks datetime-iks ilma vormingumärgita Pythoni abil dateutil:

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

print(datetime)

see parse funktsioon sõelub stringi automaatselt! Te ei pea lisama ühtegi vormingustringi. Proovime sõeluda erinevat tüüpi stringe kasutades 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')

Väljund:

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

Näete, et peaaegu igat tüüpi stringe saab hõlpsasti sõeluda kasutades dateutil moodul.

Kuigi see on mugav, meenutage varasemast, et vormingu ennustamine muudab koodi palju aeglasemaks, nii et kui teie kood nõuab suurt jõudlust, ei pruugi see teie rakenduse jaoks õige lähenemine olla.

Teisendage string kuupäevaks Mayaga

Maya muudab ka stringi sõelumise ja ajavööndite muutmise väga lihtsaks. Stringi hõlpsaks teisendamiseks Pythoni Mayaga toimige järgmiselt.

import maya

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

Väljund:

2018-04-29
17:45:25
UTC

Aja teisendamiseks teise ajavööndisse:

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)

Väljund:

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

Kas nüüd pole seda lihtne kasutada? Proovime järgi maya samade stringide komplektiga, millega oleme kasutanud 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)
    
    
    
    

Väljund:

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

Nagu näete, sõeluti kõik kuupäevavormingud edukalt!

Kui me ajavööndi teavet ei esita, teisendab see selle automaatselt UTC-ks. Seega on oluline märkida, et meie peab pakkuda to_timezone ja naive parameetrid, kui kellaaeg ei ole UTC-s.

Teisendage string noolega kuupäevaks ja kellaajaks

nool on veel üks teek Pythonis kuupäeva-kellaaja käsitlemiseks. Ja nagu varem maya, arvutab see automaatselt välja ka kuupäeva ja kellaaja vormingu. Pärast tõlgendamist tagastab see Pythoni datetime objekt alates arrow objekt

Stringi hõlpsaks teisendamiseks kuupäeva-ajaks Pythoni abil arrow:

import arrow

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

Väljund:

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

Ja siin on, kuidas saate seda kasutada arrow ajavööndite teisendamiseks, kasutades to() meetod:

import arrow

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

Väljund:

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

Nagu näete, teisendatakse kuupäeva ja kellaaja string piirkonnaks "Ameerika/New_York".

Nüüd kasutame uuesti samu stringe, mida kasutasime ülal:

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)
    
    
    
    

See kood ebaõnnestub välja kommenteeritud kuupäeva-kellaaja stringide puhul, mis on üle poole meie näidetest. Teiste stringide väljund 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

Kommenteeritavate kuupäeva-kellaaja stringide korrektseks sõelumiseks peate vastavad edastama vormingu märgid et anda raamatukogule vihjeid selle sõelumiseks.

Järeldus

Selles artiklis oleme näidanud erinevaid viise stringi sõelumiseks a-sse datetime objekt Pythonis. Võite valida Pythoni vaikeseade datetime raamatukogu või mis tahes selles artiklis mainitud kolmandate osapoolte raamatukogud.

Põhiprobleem vaikimisi datetime pakett on see, et peame peaaegu kõigi kuupäeva-kellaaja stringivormingute jaoks parsimiskoodi käsitsi määrama. Seega, kui teie stringivorming tulevikus muutub, peate tõenäoliselt muutma ka oma koodi. Kuid paljud kolmanda osapoole raamatukogud, nagu siin mainitud, tegelevad sellega automaatselt.

Veel üks probleem, millega me silmitsi seisame, on ajavööndite käsitlemine. Parim viis nende käsitlemiseks on alati salvestada aeg oma andmebaasi UTC-vormingus ja seejärel teisendada see vajaduse korral kasutaja kohalikuks ajavööndiks.

Need teegid pole head mitte ainult stringide sõelumiseks, vaid neid saab kasutada ka paljude erinevate kuupäeva ja kellaaja toimingutega seotud toimingute jaoks. Soovitan teil funktsioonide üksikasjalikuks õppimiseks dokumente läbi vaadata.

Ajatempel:

Veel alates Stackabus