Conversion de chaînes en datetime en Python

Introduction

Les données peuvent être représentées sous diverses formes - et une manière pratique de représenter les dates et les heures est instruments à cordes. Cependant, pour travailler avec ces dates et heures de manière arithmétique (comme le calcul des décalages horaires, l'ajout ou la suppression de temps, etc.) - nous devons les convertir en un datetime objet.

L'une des sources les plus courantes de datetime au format chaîne sont des API REST qui renvoient des chaînes agnostiques, que nous pouvons ensuite convertir dans d'autres formats.

De plus, les fuseaux horaires sont un casse-tête courant lorsqu'il s'agit de travailler avec des objets datetime, nous devrons donc également y penser lors de la conversion.

Dans ce guide, nous verrons comment convertir une chaîne date/heure en un datetime objet en Python, à l'aide de la fonction intégrée datetime module, mais aussi des modules tiers tels que dateutil, arrow et Maya, représentant les fuseaux horaires.

Conversion de chaînes à l'aide de datetime

La datetime module se compose de trois types d'objets différents : date, timeet datetimeL’ date l'objet contient la date, time tient le temps, et datetime détient à la fois la date et l'heure!

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

L'exécution de ce code entraînerait:

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

Lorsqu'aucune mise en forme personnalisée n'est donnée, le format de chaîne par défaut est utilisé, c'est-à-dire que le format pour "2022-12-01 10:27:03.929149" est en ISO 8601 le format (AAAA-MM-JJTHH:MM:SS.mmmmmm). Si notre chaîne d'entrée pour créer un datetime l'objet est au même format ISO 8601 ou si vous connaissez le format que vous recevrez à l'avance, nous pouvons facilement l'analyser en un datetime objet:

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)

Son exécution imprimera la date, l'heure et la date-heure :

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

Ici, nous utilisons le strptime() méthode, qui accepte deux arguments :

  • La date au format chaîne
  • Le format du premier argument

Spécifier le format comme celui-ci rend l'analyse beaucoup plus rapide puisque datetime n'a pas besoin d'essayer d'interpréter le format par lui-même, ce qui est beaucoup plus coûteux en termes de calcul. La valeur de retour est du type datetime.

Dans notre exemple, "2022-12-01 10:27:03.929149" est la chaîne d'entrée et "%Y-%m-%d %H:%M:%S.%f" est le format de notre chaîne de date. Le revenu datetime la valeur est stockée comme date_time_obj.

Puisque c'est un datetime objet, nous pouvons appeler le date() ainsi que time() méthodes directement dessus. Comme vous pouvez le voir sur la sortie, il imprime la partie "date" et "heure" de la chaîne d'entrée !

Formater les jetons

Cela vaut la peine de prendre un moment pour comprendre formater les jetons - L' "%Y-%m-%d %H:%M:%S.%f" D'avant.

Chaque jeton représente une partie différente de la date et de l'heure, comme le jour, le mois, l'année, le jour du mois ou de la semaine, etc. liste des jetons pris en charge est suffisamment étendu pour permettre divers formatages. Certains des plus couramment utilisés, que nous avons également utilisés précédemment, sont :

  • %Y: Année (4 chiffres)
  • %m: Mois
  • %d: Jour du mois
  • %H: Heure (24 heures)
  • %M: Minutes
  • %S: Secondes
  • %f: Microsecondes

Remarque: Tous ces jetons, à l'exception de l'année, devraient être complétés par des zéros (c'est-à-dire que le mois d'août est le 8ème mois et qu'ils sont complétés par des zéros jusqu'à 08).

Utilisation de jetons de format strptime() pour convertir une chaîne en un format Datetime différent

Si le format d'une chaîne est connu, il peut être facilement analysé en un datetime objet utilisant strptime(). Jetons un coup d'œil à un exemple non trivial qui se traduit d'un format à un autre :

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 chaîne d'entrée était d'un format - "17 juillet 2022 9h20". Connaissant ce format, nous avons mappé les éléments constitutifs au format ISO 8601 et l'avons converti en un datetime objet:

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

Voici une courte liste des dates-heures courantes au format chaîne et leurs formats correspondants pour 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"

Vous pouvez analyser une chaîne date-heure de n'importe quel format, tant que vous utilisez la chaîne correcte de jetons de format pour l'entrée que vous recevez.

Convertir une chaîne en Datetime avec des fuseaux horaires

La gestion des dates-heures devient plus complexe lorsqu'il s'agit de fuseaux horaires. Tous les exemples ci-dessus jusqu'à présent sont naïfs au fuseau horaire. Celles-ci sont connues sous le nom de objets datetime naïfs.

Toutefois, malgré la datetime les objets contiennent un champ exactement pour stocker les données liées au fuseau horaire - tzinfo:

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

print(dtime) 
print(dtime.tzinfo) 

La tzinfo le champ est censé être un datetime.timezone objet, indiquant les informations de fuseau horaire. C'est None par défaut, et indique que l'objet datetime est naïf de fuseau horaire. Une bibliothèque externe très courante pour gérer les fuseaux horaires est pytz. Vous pouvez définir PyTz des objets comme le tzinfo champ aussi.

Si vous ne l'avez pas déjà, installez-le via :

$ pip install pytz

En utilisant PyTz, nous pouvons créer une ancre pour les dates/heures sensibles au fuseau horaire, telles que UTC :

import datetime as dt
import pytz

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

print(dtime)
print(dtime.tzinfo)

Sortie :

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

Il n'est plus 11h, mais 2h du matin, car nous avons reculé de quelques heures le fuseau horaire ! Cette change le fuseau horaire de la date-heure.

+00:00 est la différence entre l'heure affichée et l'heure UTC comme ancre de coordination globale. Nous avons défini l'heure en UTC, donc le décalage est 00:00. Il s'agit d'une objet sensible au fuseau horaire.

De même, nous pouvons basculer l'interprétation de la même date/heure entre les fuseaux horaires. Convertissons une chaîne, telle que "2022-06-29 17:08:00" en une date/heure, puis localiser vers le fuseau horaire "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)

Remarque: Localisation transforme une date-heure naïve de fuseau horaire en une date-heure sensible au fuseau horaire et traite le fuseau horaire comme le fuseau horaire local. Ainsi, le datetime reste le même, mais étant donné le fuseau horaire différent, il ne représente plus le même point dans le temps indépendant des fuseaux horaires.

On obtient le même valeur date-heure, compensé par -04: 00 par rapport à l'heure UTC :

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

17h08 à Tokyo permettent de garantir que au même moment que 17h08 à New York. 17h08 à Tokyo est 3h08 à New York.

Comment trouver tous les codes/alias de fuseau horaire ?

Pour trouver tous les fuseaux horaires disponibles, inspectez le all_timezones champ, qui est une liste de tous les fuseaux horaires disponibles :

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

Consultez notre guide pratique et pratique pour apprendre Git, avec les meilleures pratiques, les normes acceptées par l'industrie et la feuille de triche incluse. Arrêtez de googler les commandes Git et en fait apprendre il!

There are 594 timezones in PyTz

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

Changer le fuseau horaire de Datetime

Nous pouvons convertir le fuseau horaire d'un fuseau horaire datetime objet d'une région à une autre, au lieu de localiser une date-heure naïve de fuseau horaire à travers l'objectif d'un fuseau horaire.

Ceci est différent de la localisation, car la localisation représente un point différent dans le temps, mais la conversion du fuseau horaire d'un objet représente le même point dans le temps, à travers une lentille différente :

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)

Tout d'abord, nous avons créé un objet datetime avec l'heure actuelle et l'avons défini comme fuseau horaire "America/New_York". Puis en utilisant le astimezone() méthode, nous avons converti cette datetime vers le fuseau horaire « Europe/Londres ». Tous les deux datetimes imprimera différentes valeurs, en utilisant le décalage UTC comme lien de référence entre elles :

America/New_York: 2022-11-30 21:24:30.123400-05:00
Europe/London: 2022-12-01 02:24:30.123400+00:00

2h24 le lendemain à Londres is au même moment que 21h24 la veille à New York car Londres a 5h d'avance.

Comme prévu, les dates-heures sont différentes puisqu'elles sont espacées d'environ 5 heures.

Convertir une chaîne en Datetime à l'aide de bibliothèques tierces

Python datetime module peut convertir tous les différents types de chaînes en un datetime objet. Mais le principal problème est que pour ce faire, vous devez créer la chaîne de code de formatage appropriée qui strptime() peut comprendre. La création de cette chaîne prend du temps et rend le code plus difficile à lire.

Au lieu de cela, nous pouvons utiliser d'autres bibliothèques tierces pour le rendre plus facile.

Dans certains cas, ces bibliothèques tierces ont également une meilleure prise en charge intégrée pour manipuler et comparer les dates-heures, et certaines ont même des fuseaux horaires intégrés, vous n'avez donc pas besoin d'inclure un package PyTz supplémentaire.

Examinons quelques-unes de ces bibliothèques dans les sections suivantes.

Convertir String en Datetime avec dateutil

La module dateutil est une extension de la datetime module. Un avantage est que nous n'avons pas besoin de passer de code d'analyse pour analyser une chaîne !

Pour convertir automatiquement une chaîne en datetime sans jeton de format à l'aide de Python dateutil:

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

print(datetime)

Ce parse la fonction analysera la chaîne automatiquement ! Vous n'avez pas besoin d'inclure de chaîne de format. Essayons d'analyser différents types de chaînes en utilisant 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')

Sortie :

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

Vous pouvez voir que presque n'importe quel type de chaîne peut être analysé facilement en utilisant le dateutil module.

Bien que cela soit pratique, rappelez-vous que le fait de devoir prédire le format rend le code beaucoup plus lent, donc si votre code nécessite des performances élevées, ce n'est peut-être pas la bonne approche pour votre application.

Convertir une chaîne en Datetime avec Maya

Maya facilite également l'analyse d'une chaîne et la modification des fuseaux horaires. Pour convertir facilement une chaîne avec Maya de Python :

import maya

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

Sortie :

2018-04-29
17:45:25
UTC

Pour convertir l'heure dans un autre fuseau horaire :

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)

Sortie :

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

N'est-ce pas facile à utiliser? Essayons maya avec le même ensemble de chaînes que nous avons utilisé avec 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)
    
    
    
    

Sortie :

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

Comme vous pouvez le voir, tous les formats de date ont été analysés avec succès !

Si nous ne fournissons pas les informations de fuseau horaire, il les convertit automatiquement en UTC. Il est donc important de noter que nous must fournir to_timezone ainsi que naive paramètres si l'heure n'est pas en UTC.

Convertir une chaîne en Datetime avec une flèche

flèche est une autre bibliothèque pour gérer la date et l'heure en Python. Et comme avant avec maya, il détermine également automatiquement le format datetime. Une fois interprété, il renvoie un Python datetime objet du arrow objet.

Pour convertir facilement une chaîne en datetime en utilisant Python arrow:

import arrow

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

Sortie :

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

Et voici comment vous pouvez utiliser arrow pour convertir les fuseaux horaires à l'aide de to() méthode:

import arrow

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

Sortie :

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

Comme vous pouvez le voir, la chaîne date-heure est convertie dans la région "Amérique/New_York".

Maintenant, utilisons à nouveau le même ensemble de chaînes que nous avons utilisé ci-dessus :

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)
    
    
    
    

Ce code échouera pour les chaînes date-heure qui ont été commentées, ce qui représente plus de la moitié de nos exemples. La sortie pour les autres chaînes sera :

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

Afin d'analyser correctement les chaînes date-heure qui sont commentées, vous devrez passer le correspondant formater les jetons pour donner à la bibliothèque des indices sur la façon de l'analyser.

Conclusion

Dans cet article, nous avons montré différentes manières d'analyser une chaîne en un datetime objet en Python. Vous pouvez soit opter pour le Python par défaut datetime bibliothèque ou l'une des bibliothèques tierces mentionnées dans cet article, parmi beaucoup d'autres.

Le principal problème avec la valeur par défaut datetime package est que nous devons spécifier manuellement le code d'analyse pour presque tous les formats de chaîne date-heure. Ainsi, si votre format de chaîne change à l'avenir, vous devrez probablement également modifier votre code. Mais de nombreuses bibliothèques tierces, comme celles mentionnées ici, le gèrent automatiquement.

Un autre problème auquel nous sommes confrontés concerne les fuseaux horaires. La meilleure façon de les gérer est toujours de stocker l'heure dans votre base de données au format UTC, puis de la convertir dans le fuseau horaire local de l'utilisateur si nécessaire.

Ces bibliothèques ne sont pas seulement bonnes pour l'analyse des chaînes, mais elles peuvent être utilisées pour de nombreux types d'opérations liées à la date et à l'heure. Je vous encourage à parcourir les documents pour connaître les fonctionnalités en détail.

Horodatage:

Plus de Stackabuse