Conversione di stringhe in datetime in Python

Introduzione

I dati possono essere rappresentati in varie forme e un modo conveniente per rappresentare date e orari lo sono stringhe. Tuttavia, per lavorare con queste date e ore in modo aritmetico (come calcolare le differenze di orario, aggiungere o rimuovere l'ora, ecc.), dobbiamo convertirle in un datetime oggetto.

Una delle fonti più comuni di datetime in formato stringa sono API REST che restituiscono stringhe agnostiche, che possiamo poi convertire in altri formati.

Inoltre, i fusi orari sono un mal di testa comune quando si tratta di lavorare con oggetti datetime, quindi dovremo pensarci anche durante la conversione.

In questa guida, daremo un'occhiata a come convertire una data/ora di una stringa in un formato a datetime oggetto in Python, usando il built-in datetime modulo, ma anche moduli di terze parti come dateutil, arrow e Maya, tenendo conto dei fusi orari.

Conversione di stringhe utilizzando datetime

I datetime Il modulo è costituito da tre diversi tipi di oggetto: date, timee datetime. date l'oggetto contiene la data, time tiene il tempo, e datetime contiene sia la data che l'ora!

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

L'esecuzione di questo codice comporterebbe:

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

Quando non viene fornita alcuna formattazione personalizzata, viene utilizzato il formato di stringa predefinito, ovvero il formato per "2022-12-01 10:27:03.929149" è in ISO 8601 formato (AAAA-MM-GGTHH:MM:SS.mmmmmm). Se la nostra stringa di input per creare a datetime l'oggetto è nello stesso formato ISO 8601 o se conosci il formato che riceverai in anticipo, possiamo facilmente analizzarlo in un datetime oggetto:

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)

Eseguendolo stamperà la data, l'ora e la data-ora:

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

Qui, usiamo il strptime() metodo, che accetta due argomenti:

  • La data in formato stringa
  • Il formato del primo argomento

Specificare il formato in questo modo rende l'analisi molto più veloce da allora datetime non ha bisogno di provare a interpretare il formato da solo, che è molto più costoso dal punto di vista computazionale. Il valore restituito è del tipo datetime.

Nel nostro esempio, "2022-12-01 10:27:03.929149" è la stringa di input e "%Y-%m-%d %H:%M:%S.%f" è il formato della nostra stringa di data. Il restituito datetime il valore è memorizzato come date_time_obj.

Dal momento che questo è un datetime oggetto, possiamo chiamare il date() ed time() metodi direttamente su di esso. Come puoi vedere dall'output, stampa la parte "data" e "ora" della stringa di input!

Formattare i token

Vale la pena prendersi un momento per capire token di formato - Il "%Y-%m-%d %H:%M:%S.%f" da prima.

Ogni token rappresenta una parte diversa della data-ora, come giorno, mese, anno, giorno del mese o settimana, ecc. elenco dei token supportati è sufficientemente esteso da consentire varie formattazioni. Alcuni di quelli comunemente usati, che abbiamo usato anche in precedenza sono:

  • %Y: Anno (4 cifre)
  • %m: Mese
  • %d: Giorno del mese
  • %H: Ora (24 ore)
  • %M: Minuti
  • %S: Secondi
  • %f: Microsecondi

Nota: Tutti questi token, eccetto l'anno, dovrebbero essere riempiti con zero (ad esempio agosto è l'ottavo mese ed è riempito con zero per 08).

Utilizzo dei token di formato strptime() per convertire la stringa in un formato data/ora diverso

Se il formato di una stringa è noto, può essere facilmente analizzato in a datetime oggetto usando strptime(). Diamo un'occhiata a un esempio non banale che traduce da un formato all'altro:

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)

La stringa di input era di un formato: "17 luglio 2022 9:20". Conoscendo questo formato, abbiamo mappato gli elementi costitutivi nel formato ISO 8601 e li abbiamo convertiti in a datetime oggetto:

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

Di seguito è riportato un breve elenco di date e orari in formato stringa comuni e i formati corrispondenti per 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"

Puoi analizzare una stringa data-ora di qualsiasi formato, purché utilizzi la stringa corretta di token di formato per l'input che stai ricevendo.

Converti stringa in data e ora con fusi orari

La gestione della data e dell'ora diventa più complessa quando si ha a che fare con i fusi orari. Tutti gli esempi precedenti finora sono ingenui rispetto al fuso orario. Questi sono noti come oggetti datetime ingenui.

Tuttavia, la datetime gli oggetti contengono un campo esattamente per la memorizzazione dei dati relativi al fuso orario – tzinfo:

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

print(dtime) 
print(dtime.tzinfo) 

I tzinfo campo è destinato ad essere un datetime.timezone oggetto, che denota le informazioni sul fuso orario. Suo None per impostazione predefinita e indica che l'oggetto datetime è ingenuo nel fuso orario. Una libreria esterna molto comune per la gestione dei fusi orari è pytz. Puoi impostare PyTz oggetti come il tzinfo anche sul campo.

Se non lo hai già, installalo tramite:

$ pip install pytz

Usando PyTz, possiamo creare un'ancora per date e orari sensibili al fuso orario, come UTC:

import datetime as dt
import pytz

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

print(dtime)
print(dtime.tzinfo)

Produzione:

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

Non sono più le 11:2, ma le XNUMX:XNUMX, perché abbiamo impostato il fuso orario indietro di qualche ora! Questo cambia il fuso orario della data e ora.

+00:00 è la differenza tra l'ora visualizzata e l'ora UTC come ancoraggio di coordinamento globale. Abbiamo impostato l'ora in UTC, quindi l'offset è 00:00. Questo è un oggetto che riconosce il fuso orario.

Allo stesso modo, possiamo scambiare la stessa interpretazione di datetime tra fusi orari. Convertiamo una stringa, come "2022-06-29 17:08:00" in una data e ora e poi localizzare nel fuso orario "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)

Nota: Localizzazione trasforma un datetime ingenuo nel fuso orario in un datetime che riconosce il fuso orario e tratta il fuso orario come quello locale. Così, il datetime rimane lo stesso, ma dato il diverso fuso orario, non rappresenta più lo stesso punto nel tempo non associato ai fusi orari.

Otteniamo lo stesso valore data/ora, compensato da -04: 00 rispetto all'ora UTC:

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

17:08 a Tokio non stiano lo stesso punto nel tempo delle 17:08 a New York. Le 17:08 a Tokyo sono le 3:08 a New York.

Come trovare tutti i codici/alias di fuso orario?

Per trovare tutti i fusi orari disponibili, controlla il file all_timezones campo, che è un elenco di tutti i fusi orari disponibili:

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

Dai un'occhiata alla nostra guida pratica e pratica per l'apprendimento di Git, con le migliori pratiche, gli standard accettati dal settore e il cheat sheet incluso. Smetti di cercare su Google i comandi Git e in realtà imparare esso!

There are 594 timezones in PyTz

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

Cambia il fuso orario di Datetime

Possiamo convertire il fuso orario di un fuso orario datetime oggetto da una regione all'altra, invece di localizzare un datetime ingenuo di fuso orario attraverso l'obiettivo di un fuso orario.

Questo è diverso dalla localizzazione, poiché la localizzazione rappresenta un punto nel tempo diverso, ma la conversione del fuso orario di un oggetto rappresenta lo stesso punto nel tempo, attraverso una lente diversa:

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)

Innanzitutto, abbiamo creato un oggetto datetime con l'ora corrente e lo abbiamo impostato come fuso orario "America/New_York". Quindi utilizzando il astimezone() metodo, abbiamo convertito questo datetime al fuso orario "Europa/Londra". Entrambi datetimes stamperà valori diversi, utilizzando l'offset UTC come collegamento di riferimento tra di loro:

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 il giorno successivo a Londra is lo stesso momento delle 21:24 del giorno precedente a New York dato che Londra è avanti di 5 ore.

Come previsto, le date e le ore sono diverse poiché sono a circa 5 ore di distanza.

Converti stringa in data e ora utilizzando librerie di terze parti

Python's datetime Il modulo può convertire tutti i diversi tipi di stringhe in a datetime oggetto. Ma il problema principale è che per fare ciò è necessario creare la stringa di codice di formattazione appropriata che strptime() posso capire. La creazione di questa stringa richiede tempo e rende il codice più difficile da leggere.

Invece, possiamo usare altre librerie di terze parti per renderlo più semplice.

In alcuni casi queste librerie di terze parti hanno anche un migliore supporto integrato per la manipolazione e il confronto di date-ora, e alcune hanno anche fusi orari integrati, quindi non è necessario includere un pacchetto PyTz aggiuntivo.

Diamo un'occhiata ad alcune di queste librerie nelle sezioni seguenti.

Converti stringa in Datetime con dateutil

I modulo dateutil è un'estensione di datetime modulo. Un vantaggio è che non abbiamo bisogno di passare alcun codice di analisi per analizzare una stringa!

Per convertire automaticamente una stringa in datetime senza un token di formato usando Python dateutil:

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

print(datetime)

La sezione parse la funzione analizzerà automaticamente la stringa! Non è necessario includere alcuna stringa di formato. Proviamo ad analizzare diversi tipi di stringhe utilizzando 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')

Produzione:

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

Puoi vedere che quasi ogni tipo di stringa può essere analizzato facilmente usando il file dateutil modulo.

Sebbene ciò sia conveniente, ricorda da prima che dover prevedere il formato rende il codice molto più lento, quindi se il tuo codice richiede prestazioni elevate, questo potrebbe non essere l'approccio giusto per la tua applicazione.

Converti stringa in data e ora con Maya

Maya rende anche molto facile analizzare una stringa e modificare i fusi orari. Per convertire facilmente una stringa con Maya di Python:

import maya

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

Produzione:

2018-04-29
17:45:25
UTC

Per convertire l'ora in un fuso orario diverso:

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)

Produzione:

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

Ora non è così facile da usare? Proviamo maya con lo stesso set di corde con cui abbiamo usato 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)
    
    
    
    

Produzione:

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

Come puoi vedere, tutti i formati di data sono stati analizzati correttamente!

Se non forniamo le informazioni sul fuso orario, le converte automaticamente in UTC. Quindi, è importante notare che noi devono obbligatoriamente: fornire il to_timezone ed naive parametri se l'ora non è in UTC.

Converti stringa in data e ora con freccia

freccia è un'altra libreria per gestire datetime in Python. E come prima con maya, calcola automaticamente anche il formato datetime. Una volta interpretato, restituisce un Python datetime oggetto dal arrow oggetto.

Per convertire facilmente una stringa in datetime usando Python arrow:

import arrow

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

Produzione:

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

Ed ecco come puoi usare arrow per convertire i fusi orari utilizzando il file to() Metodo:

import arrow

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

Produzione:

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

Come puoi vedere, la stringa data-ora viene convertita nella regione "America/New_York".

Ora, usiamo di nuovo lo stesso insieme di stringhe che abbiamo usato sopra:

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)
    
    
    
    

Questo codice avrà esito negativo per le stringhe di data e ora che sono state commentate, ovvero oltre la metà dei nostri esempi. L'output per le altre stringhe sarà:

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

Per analizzare correttamente le stringhe data-ora che sono commentate, dovrai passare il corrispondente token di formato per dare alla biblioteca indizi su come analizzarlo.

Conclusione

In questo articolo abbiamo mostrato diversi modi per analizzare una stringa in a datetime oggetto in Python. Puoi optare per il Python predefinito datetime library o una qualsiasi delle librerie di terze parti menzionate in questo articolo, tra molte altre.

Il problema principale con il default datetime package è che dobbiamo specificare manualmente il codice di analisi per quasi tutti i formati di stringhe data-ora. Quindi, se il formato della tua stringa cambia in futuro, probabilmente dovrai cambiare anche il tuo codice. Ma molte librerie di terze parti, come quelle menzionate qui, lo gestiscono automaticamente.

Un altro problema che dobbiamo affrontare riguarda i fusi orari. Il modo migliore per gestirli è sempre memorizzare l'ora nel database come formato UTC e quindi convertirla nel fuso orario locale dell'utente quando necessario.

Queste librerie non sono utili solo per l'analisi delle stringhe, ma possono essere utilizzate per molti tipi diversi di operazioni relative alla data e all'ora. Ti incoraggio a esaminare i documenti per apprendere le funzionalità in dettaglio.

Timestamp:

Di più da Impilamento