web-dev-qa-db-fra.com

Conversion de chaîne en date / heure

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.

1953
Oli

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:

Remarques:

  • strptime = "durée d'analyse de la chaîne"
  • strftime = "heure du format de chaîne"
  • Prononcez-le à voix haute aujourd'hui, vous n'aurez plus à le chercher dans 6 mois.
3114
Patrick Harrington

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
746
Simon Willison

Découvrez strptime dans le module 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)
475
florin

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)]
44
Rizwan Mumtaz

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)))
31
Janus Troelsen

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

25
Alexander

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"))​​​​​​​
23
Aram Kocharyan

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

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.

21
user1767754

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.
14
Ryu_hayabusa
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
13
guneysus

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')
12
Toskan

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:

  • Si vous ne transmettez aucun argument, la date du jour sera renvoyée.
  • Il existe un format de date par défaut que vous pouvez remplacer.
  • Vous pouvez facilement le modifier pour renvoyer une date/heure.
10
Mackraken

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
8
Rajiv Sharma

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.

7
Bill Bell

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)
6
Kanish Mathew

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')
5
Raphael Amoedo

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.

3
Javed

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.

0
Domi W
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
0
Riz.Khan