python yyyy Conversion de chaîne en date-heure




timestamp python (14)

Personnellement, j'aime la solution en utilisant le module parser , qui est la deuxième réponse à cette question et est belle, car vous n'avez pas besoin de construire des littéraux de chaîne pour le faire fonctionner. Cependant, un inconvénient, il 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 le faites pas encore a million fois, je pense que la méthode parser est plus pratique et qu'elle va gérer la plupart des formats de temps automatiquement.

Court et simple. 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 des champs datetime corrects dans une base de données, j'ai donc besoin de les transformer en objets datetime réels.

Toute aide (même si c'est juste un coup de pied dans la bonne direction) serait appréciée.

Edit: Cela passe par l'ORM de Django, donc je ne peux pas utiliser SQL pour faire la conversion sur insert.


Vois ma réponse .

Dans les données réelles, il s'agit d'un réel problème: formats de date multiples, non concordants, incomplets, incohérents et multilingues, souvent mélangés librement dans un ensemble de données. Ce n'est pas normal que le code de production échoue, et encore moins que l'exception soit heureuse comme un renard.

Nous devons essayer ... attraper plusieurs formats datetime fmt1, fmt2, ..., fmtn et supprimer / gérer les exceptions (de strptime() ) pour tous ceux qui ne correspondent pas (et en particulier, éviter d'avoir besoin d'un yukky n-deep indenté échelle des clauses try..catch). Voir ma solution


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

J'ai mis en place un projet qui peut convertir des expressions vraiment soignées. Vérifiez les timestring .

Voici quelques exemples ci-dessous:

pip install timestring
>>> import timestring
>>> timestring.Date('monday, aug 15th 2015 at 8:40 pm')
<timestring.Date 2015-08-15 20:40:00 4491909392>
>>> timestring.Date('monday, aug 15th 2015 at 8:40 pm').date
datetime.datetime(2015, 8, 15, 20, 40)
>>> timestring.Range('next week')
<timestring.Range From 03/10/14 00:00:00 to 03/03/14 00:00:00 4496004880>
>>> (timestring.Range('next week').start.date, timestring.Range('next week').end.date)
(datetime.datetime(2014, 3, 10, 0, 0), datetime.datetime(2014, 3, 14, 0, 0))

Voici deux solutions utilisant Pandas pour convertir des dates formatées en chaînes 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 de 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 Timestamps en utilisant to_datetime , donc vérifiez les docs si vous avez besoin de quelque chose de spécial.

De même, les horodatages ont de nombreuses propriétés et méthodes accessibles en plus de .date


Beaucoup d'horodatages ont un fuseau horaire implicite. Pour vous assurer que votre code fonctionnera dans chaque fuseau horaire, 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)))

Cette question a été visitée plusieurs fois mais la flèche n'a pas été mentionnée, et elle offre de nombreuses fonctions utiles pour les dates et heures. Ce morceau de code fournit une réponse à la question et montre que la flèche est également capable de formater les dates facilement 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.


Exemple d'objet datetime avec Django Timezone.

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 quand 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.

Vous pouvez utiliser easy_date pour le rendre facile:

import date_converter
converted_date = date_converter.string_to_datetime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')

Créer 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:

  • Si vous ne passez aucun argument, il retournera la date du jour.
  • theres un format de date par défaut que vous pouvez remplacer.
  • Vous pouvez facilement le modifier pour renvoyer un datetime.

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 passer vos valeurs de chaîne séparées pour le 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 dans le formate de date.


Souvenez-vous de cela et vous n'avez pas eu besoin de vous perdre dans la conversion de date / heure.

Chaîne à l'objet datetime = strptime

Objet datetime à d'autres formats = strftime

Jun 1 2005 1:33PM

est égal à

%b %d %Y %I:%M%p

% b Mois en tant que nom abrégé de l'environnement local (juin)

% d Jour du mois en tant que nombre décimal à remplissage nul (1)

% Y Année avec le siècle comme nombre décimal (2015)

% I Heure (horloge de 12 heures) en tant que nombre décimal à remplissage nul (01)

% M Minute en tant que nombre décimal à remplissage nul (33)

% p Équivalent local de AM ou PM (PM)

donc vous avez besoin de strptime c'est-à-dire la conversion de la string à

>>> 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

Que faire si vous avez un format différent de dates que 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)]

datetime.strptime est la routine principale pour l'analyse des chaînes en datetime. Il peut gérer toutes sortes de formats, avec le format déterminé par une chaîne de format que vous lui donnez:

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 de fuseau horaire.

Liens:

Remarques:

  • strptime = "temps d'analyse de chaîne"
  • strftime = "heure de format de chaîne"
  • Prononcez-le à haute voix aujourd'hui et vous n'aurez plus à le chercher dans 6 mois.

Découvrez strptime dans le module de time . C'est l'inverse de strftime .

$ python
>>> import time
>>> time.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')
time.struct_time(tm_year=2005, tm_mon=6, tm_mday=1,
                 tm_hour=13, tm_min=33, tm_sec=0,
                 tm_wday=2, tm_yday=152, tm_isdst=-1)




datetime