J'ai une énorme liste de dates comme celle-ci:
Jun 1 2005 1:33PM
Aug 28 1999 12:00AM
Je vais les replacer dans les champs de date/heure appropriés d'une base de données, donc j'ai besoin de les transformer en objets datetime réels.
Cela passe par ORM de Django, je ne peux donc pas utiliser SQL pour effectuer la conversion lors de l'insertion.
datetime.strptime
est la routine principale pour analyser les chaînes en dates/heures. Il peut gérer toutes sortes de formats, le format étant déterminé par une chaîne de format que vous lui attribuez:
from datetime import datetime
datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
L'objet datetime
résultant est naïf pour le fuseau horaire.
Liens:
Documentation Python pour strptime
/strftime
chaînes de format: Python 2 , Python
strftime.org est aussi une très bonne référence pour strftime
Remarques:
strptime
= "durée d'analyse de la chaîne"strftime
= "heure du format de chaîne"Utilisez le tiers dateutil bibliothèque:
from dateutil import parser
dt = parser.parse("Aug 28 1999 12:00AM")
Il peut gérer la plupart des formats de date, y compris celui que vous devez analyser. C'est plus pratique que strptime, car il permet de deviner le bon format la plupart du temps.
C'est très utile pour écrire des tests, où la lisibilité est plus importante que la performance.
Vous pouvez l'installer avec:
pip install python-dateutil
Souvenez-vous de cela et vous n'avez plus besoin de vous perdre dans la conversion de date/heure.
Chaîne en objet datetime = strptime
objet datetime à d'autres formats = strftime
Jun 1 2005 1:33PM
est égal à
%b %d %Y %I:%M%p
% b Mois comme nom abrégé de l’environnement local (juin)
% d Jour du mois sous forme de nombre décimal zéro-complété (1)
% Y Année avec siècle sous forme décimale (2015)
% I heure (horloge sur 12 heures) sous forme de nombre décimal complété à zéro (01)
% M Minute sous forme de nombre décimal zéro-complété (33)
% p équivalent de la langue locale soit le matin soit le soir
vous avez donc besoin de convertir strptime i-e string
en
>>> dates = []
>>> dates.append('Jun 1 2005 1:33PM')
>>> dates.append('Aug 28 1999 12:00AM')
>>> from datetime import datetime
>>> for d in dates:
... date = datetime.strptime(d, '%b %d %Y %I:%M%p')
... print type(date)
... print date
...
Sortie
<type 'datetime.datetime'>
2005-06-01 13:33:00
<type 'datetime.datetime'>
1999-08-28 00:00:00
Et si vous avez un format de date différent, vous pouvez utiliser panda ou dateutil.parse
>>> import dateutil
>>> dates = []
>>> dates.append('12 1 2017')
>>> dates.append('1 1 2017')
>>> dates.append('1 12 2017')
>>> dates.append('June 1 2017 1:30:00AM')
>>> [parser.parse(x) for x in dates]
Sortie
[datetime.datetime(2017, 12, 1, 0, 0), datetime.datetime(2017, 1, 1, 0, 0), datetime.datetime(2017, 1, 12, 0, 0), datetime.datetime(2017, 6, 1, 1, 30)]
De nombreux horodatages ont un fuseau horaire implicite. Pour vous assurer que votre code fonctionnera dans tous les fuseaux horaires, vous devez utiliser l'UTC en interne et attacher un fuseau horaire chaque fois qu'un objet étranger entre dans le système.
Python 3.2+:
>>> datetime.datetime.strptime(
... "March 5, 2014, 20:13:50", "%B %d, %Y, %H:%M:%S"
... ).replace(tzinfo=datetime.timezone(datetime.timedelta(hours=-3)))
Voici deux solutions utilisant Pandas pour convertir des dates au format chaîne en objets datetime.date.
import pandas as pd
dates = ['2015-12-25', '2015-12-26']
# 1) Use a list comprehension.
>>> [d.date() for d in pd.to_datetime(dates)]
[datetime.date(2015, 12, 25), datetime.date(2015, 12, 26)]
# 2) Convert the dates to a DatetimeIndex and extract the python dates.
>>> pd.DatetimeIndex(dates).date.tolist()
[datetime.date(2015, 12, 25), datetime.date(2015, 12, 26)]
Timings
dates = pd.DatetimeIndex(start='2000-1-1', end='2010-1-1', freq='d').date.tolist()
>>> %timeit [d.date() for d in pd.to_datetime(dates)]
# 100 loops, best of 3: 3.11 ms per loop
>>> %timeit pd.DatetimeIndex(dates).date.tolist()
# 100 loops, best of 3: 6.85 ms per loop
Et voici comment convertir les exemples date-heure d'origine de l'OP:
datetimes = ['Jun 1 2005 1:33PM', 'Aug 28 1999 12:00AM']
>>> pd.to_datetime(datetimes).to_pydatetime().tolist()
[datetime.datetime(2005, 6, 1, 13, 33),
datetime.datetime(1999, 8, 28, 0, 0)]
Il existe de nombreuses options pour convertir les chaînes en Pandas Horodatages à l'aide de to_datetime
, donc vérifiez docs si vous avez besoin de quelque chose de spécial.
De même, les horodatages ont de nombreux propriétés et méthodes accessibles en plus de .date
Quelque chose qui n'est pas mentionné ici et qui est utile: ajouter un suffixe à la journée. J'ai découplé la logique de suffixe afin que vous puissiez l'utiliser pour n'importe quel nombre, pas seulement pour les dates.
import time
def num_suffix(n):
'''
Returns the suffix for any given int
'''
suf = ('th','st', 'nd', 'rd')
n = abs(n) # wise guy
tens = int(str(n)[-2:])
units = n % 10
if tens > 10 and tens < 20:
return suf[0] # teens with 'th'
Elif units <= 3:
return suf[units]
else:
return suf[0] # 'th'
def day_suffix(t):
'''
Returns the suffix of the given struct_time day
'''
return num_suffix(t.tm_mday)
# Examples
print num_suffix(123)
print num_suffix(3431)
print num_suffix(1234)
print ''
print day_suffix(time.strptime("1 Dec 00", "%d %b %y"))
print day_suffix(time.strptime("2 Nov 01", "%d %b %y"))
print day_suffix(time.strptime("3 Oct 02", "%d %b %y"))
print day_suffix(time.strptime("4 Sep 03", "%d %b %y"))
print day_suffix(time.strptime("13 Nov 90", "%d %b %y"))
print day_suffix(time.strptime("14 Oct 10", "%d %b %y"))
Dans Python> = 3.7.0,
convertir chaîne AAAA-MM-JJ en objet datetime, datetime.fromisoformat
peut être utilisé.
>>> from datetime import datetime
>>> date_string = "2012-12-12 10:10:10"
>>> print (datetime.fromisoformat(date_string))
>>> 2012-12-12 10:10:10
Personnellement, j'aime bien la solution utilisant le module parser
, qui est la deuxième réponse à cette question et qui est belle, car vous n'avez pas à construire de littéraux de chaîne pour que cela fonctionne. MAIS, un inconvénient est que c'est 90% plus lent que la réponse acceptée avec strptime
.
from dateutil import parser
from datetime import datetime
import timeit
def dt():
dt = parser.parse("Jun 1 2005 1:33PM")
def strptime():
datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
print(timeit.timeit(stmt=dt, number=10**5))
print(timeit.timeit(stmt=strptime, number=10**5))
>10.70296801342902
>1.3627995655316933
Tant que vous ne faites pas cela un million de fois encore et encore, je pense toujours que la méthode parser
est plus pratique et gérera la plupart des formats de temps automatiquement.
Exemple d'objet datetime compatible avec le fuseau horaire Django.
import datetime
from Django.utils.timezone import get_current_timezone
tz = get_current_timezone()
format = '%b %d %Y %I:%M%p'
date_object = datetime.datetime.strptime('Jun 1 2005 1:33PM', format)
date_obj = tz.localize(date_object)
Cette conversion est très importante pour Django et Python lorsque vous avez USE_TZ = True
:
RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
In [34]: import datetime
In [35]: _now = datetime.datetime.now()
In [36]: _now
Out[36]: datetime.datetime(2016, 1, 19, 9, 47, 0, 432000)
In [37]: print _now
2016-01-19 09:47:00.432000
In [38]: _parsed = datetime.datetime.strptime(str(_now),"%Y-%m-%d %H:%M:%S.%f")
In [39]: _parsed
Out[39]: datetime.datetime(2016, 1, 19, 9, 47, 0, 432000)
In [40]: assert _now == _parsed
pour le format unix/mysql 2018-10-15 20:59:29
from datetime import datetime
datetime_object = datetime.strptime('2018-10-15 20:59:29', '%Y-%m-%d %H:%M:%S')
Créez une petite fonction utilitaire comme:
def date(datestr="", format="%Y-%m-%d"):
from datetime import datetime
if not datestr:
return datetime.today().date()
return datetime.strptime(datestr, format).date()
C'est assez polyvalent:
Le module date/heure Python permet de récupérer l'heure et de convertir les formats de date/heure.
import datetime
new_date_format1 = datetime.datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
new_date_format2 = datetime.datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p').strftime('%Y/%m/%d %I:%M%p')
print new_date_format1
print new_date_format2
Sortie:
2005-06-01 13:33:00
2005/06/01 01:33PM
La flèche offre de nombreuses fonctions utiles pour les dates et les heures. Ce morceau de code fournit une réponse à la question et montre que arrow est également capable de formater facilement les dates et d'afficher des informations pour d'autres paramètres régionaux.
>>> import arrow
>>> dateStrings = [ 'Jun 1 2005 1:33PM', 'Aug 28 1999 12:00AM' ]
>>> for dateString in dateStrings:
... dateString
... arrow.get(dateString.replace(' ',' '), 'MMM D YYYY H:mmA').datetime
... arrow.get(dateString.replace(' ',' '), 'MMM D YYYY H:mmA').format('ddd, Do MMM YYYY HH:mm')
... arrow.get(dateString.replace(' ',' '), 'MMM D YYYY H:mmA').humanize(locale='de')
...
'Jun 1 2005 1:33PM'
datetime.datetime(2005, 6, 1, 13, 33, tzinfo=tzutc())
'Wed, 1st Jun 2005 13:33'
'vor 11 Jahren'
'Aug 28 1999 12:00AM'
datetime.datetime(1999, 8, 28, 0, 0, tzinfo=tzutc())
'Sat, 28th Aug 1999 00:00'
'vor 17 Jahren'
Voir http://arrow.readthedocs.io/en/latest/ pour plus d'informations.
Ce serait utile pour convertir une chaîne en date/heure et aussi avec fuseau horaire
def convert_string_to_time(date_string, timezone):
from datetime import datetime
import pytz
date_time_obj = datetime.strptime(date_string[:26], '%Y-%m-%d %H:%M:%S.%f')
date_time_obj_timezone = pytz.timezone(timezone).localize(date_time_obj)
return date_time_obj_timezone
date = '2018-08-14 13:09:24.543953+00:00'
TIME_ZONE = 'UTC'
date_time_obj_timezone = convert_string_to_time(date, TIME_ZONE)
Vous pouvez utiliser easy_date pour simplifier les choses:
import date_converter
converted_date = date_converter.string_to_datetime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
Si vous voulez seulement le format de date, vous pouvez le convertir manuellement en passant vos champs individuels comme:
>>> import datetime
>>> date = datetime.date(int('2017'),int('12'),int('21'))
>>> date
datetime.date(2017, 12, 21)
>>> type(date)
<type 'datetime.date'>
Vous pouvez transmettre vos valeurs de chaîne fractionnée pour les convertir en type de date, comme:
selected_month_rec = '2017-09-01'
date_formate = datetime.date(int(selected_month_rec.split('-')[0]),int(selected_month_rec.split('-')[1]),int(selected_month_rec.split('-')[2]))
Vous obtiendrez la valeur résultante au format de date.
Vous pouvez également utiliser le canard de facebook.
Essayez-le en ligne ici: https://duckling.wit.ai/
Il y a un wrapper python pour la bibliothèque: pip install duckling
Il prend en charge beaucoup plus que la seule analyse du temps.
emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")
emp.info()
il affiche la colonne "Date de début" et "Heure de la dernière connexion" sont toutes les deux "objet = chaînes" dans le cadre de données
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 8 columns):
First Name 933 non-null object
Gender 855 non-null object
Start Date 1000 non-null object Last Login Time 1000 non-null object
Salary 1000 non-null int64
Bonus % 1000 non-null float64
Senior Management 933 non-null object
Team 957 non-null object
dtypes: float64(1), int64(1), object(6)
memory usage: 62.6+ KB
En utilisant l'option parse_dates
dans read_csv
mention, vous pouvez convertir votre chaîne datetime en format pandas datetime.
emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv", parse_dates=["Start Date", "Last Login Time"])
emp.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 8 columns):
First Name 933 non-null object
Gender 855 non-null object
Start Date 1000 non-null datetime64[ns] Last Login Time 1000 non-null datetime64[ns]
Salary 1000 non-null int64
Bonus % 1000 non-null float64
Senior Management 933 non-null object
Team 957 non-null object
dtypes: datetime64[ns](2), float64(1), int64(1), object(4)
memory usage: 62.6+ KB