it-swarm-es.tech

Convertir cadena en fecha y hora

Corto y sencillo. Tengo una gran lista de fechas y fechas como estas:

Jun 1 2005  1:33PM
Aug 28 1999 12:00AM

Voy a volver a colocarlos en campos de fecha y hora adecuados en una base de datos, así que necesito hacerles magia en objetos de fecha y hora reales.

Cualquier ayuda (incluso si es solo una patada en la dirección correcta) sería apreciada.

Edición: Esto está pasando por el ORM de Django, por lo que no puedo usar SQL para hacer la conversión al insertar.

1838
Oli

datetime.strptime es la rutina principal para analizar cadenas en tiempos de datos. Puede manejar todo tipo de formatos, con el formato determinado por una cadena de formato que le des:

from datetime import datetime

datetime_object = datetime.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')

El objeto datetime resultante es un huso horario.

Campo de golf:

Notas:

  • strptime = "tiempo de análisis de cadena"
  • strftime = "tiempo de formato de cadena"
  • Pronuncialo en voz alta hoy y no tendrás que buscarlo nuevamente en 6 meses.
2933
Patrick Harrington

Utilice el tercero dateutil library:

from dateutil import parser
dt = parser.parse("Aug 28 1999 12:00AM")

Puede manejar la mayoría de los formatos de fecha, incluido el que necesita analizar. Es más conveniente que strptime, ya que puede adivinar el formato correcto la mayor parte del tiempo.

Es muy útil para escribir pruebas, donde la legibilidad es más importante que el rendimiento.

Puedes instalarlo con:

pip install python-dateutil
712
Simon Willison

Echa un vistazo a strptime en el módulo time . Es el inverso 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)
470
florin

Recuerda esto y no necesitas volver a confundirte en la conversión de fecha y hora.

Cadena al objeto datetime = strptime

objeto datetime a otros formatos = strftime

Jun 1 2005 1:33PM

es igual a

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

% b Mes como nombre abreviado de la localidad (junio)

% d Día del mes como un número decimal con cero (1)

% Y Año con siglo como número decimal (2015)

% I hora (reloj de 12 horas) como un número decimal sin relleno (01)

% M minuto como un número decimal con cero (33)

El equivalente de% p Locale de AM o PM (PM)

por lo que necesita strptime i-e que convierte string a

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

Salida

<type 'datetime.datetime'>
2005-06-01 13:33:00
<type 'datetime.datetime'>
1999-08-28 00:00:00

¿Qué pasa si tienes un formato diferente de fechas puedes usar panda o 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]

Salida

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

Muchas marcas de tiempo tienen una zona horaria implícita. Para asegurarse de que su código funcione en cada zona horaria, debe usar UTC internamente y adjuntar una zona horaria cada vez que un objeto extraño ingrese al sistema.

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

Aquí hay dos soluciones que usan Pandas para convertir fechas formateadas como cadenas en objetos 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)]

Tiempos

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

Y aquí es cómo convertir los ejemplos de fecha y hora originales del 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)]

Hay muchas opciones para convertir las cadenas a marcas de tiempo de Pandas usando to_datetime, así que verifique el docs si necesita algo especial.

Del mismo modo, las marcas de tiempo tienen muchos propiedades y métodos a los que se puede acceder además de .date

23
Alexander

Algo que no se menciona aquí y es útil: agregar un sufijo al día. Desacoplé la lógica del sufijo para que pueda usarlo para cualquier número que desee, no solo fechas.

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

Personalmente, me gusta la solución utilizando el módulo parser, que es la segunda respuesta a esta pregunta y es hermosa, ya que no tienes que construir literales de cadena para que funcione.PERO, un inconveniente es que es 90% más lento que la respuesta aceptada con 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

Mientras no esté haciendo esto un millón veces una y otra vez, sigo pensando que el método parser es más conveniente y manejará la mayoría de los formatos de tiempo automáticamente.

18
user1767754

Ejemplo de objeto de fecha y hora 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)

Esta conversión es muy importante para Django y Python cuando tienes 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
12
guneysus

para el formato 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

Crea una pequeña función de utilidad como:

def date(datestr="", format="%Y-%m-%d"):
    from datetime import datetime
    if not datestr:
        return datetime.today().date()
    return datetime.strptime(datestr, format).date()

Esto es lo suficientemente versátil:

  • Si no pasa ningún argumento volverá la fecha de hoy.
  • Hay un formato de fecha como predeterminado que puede anular.
  • Puede modificarlo fácilmente para devolver un datetime.
9
Mackraken

En Python> = 3.7.0,

para convertir cadena YYYY-MM-DD a objeto datetime , datetime.fromisoformat podría ser utilizado.

>>> from datetime import datetime

>>> date_string = "2012-12-12 10:10:10"
>>> print (datetime.fromisoformat(date_string))
>>> 2012-12-12 10:10:10
9
SuperNova

El módulo datetime Python es bueno para obtener los formatos de fecha y hora de fecha.

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

Salida:

2005-06-01 13:33:00
2005/06/01 01:33PM
8
Rajiv Sharma

arrow ofrece muchas funciones útiles para fechas y horas. Este bit de código proporciona una respuesta a la pregunta y muestra que la flecha también es capaz de formatear fechas fácilmente y mostrar información de otras configuraciones regionales.

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

Consulte http://arrow.readthedocs.io/en/latest/ para obtener más información.

7
Bill Bell

Puede usar easy_date para hacerlo más fácil:

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

Sería útil para convertir la cadena a datetime y también con la zona horaria

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

Si solo desea el formato de fecha, puede convertirlo manualmente pasando sus campos individuales como:

>>> import datetime
>>> date = datetime.date(int('2017'),int('12'),int('21'))
>>> date
datetime.date(2017, 12, 21)
>>> type(date)
<type 'datetime.date'>

Puede pasar sus valores de cadena dividida para convertirlos en un tipo de fecha como:

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

Obtendrá el valor resultante en formato de fecha.

3
Javed

También puedes usar el patito de facebook.

Pruébelo en línea aquí: https://duckling.wit.ai/

Hay una envoltura de python para la biblioteca: pip install duckling

Soporta mucho más que solo analizar el tiempo.

0
Domi W
emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")
emp.info()

muestra la columna "Fecha y hora de inicio" y "Última hora de inicio de sesión", ambas son "objeto = cadenas" en el marco de datos

<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

Al usar la opción parse_dates en read_csv, puede convertir su cadena datetime en el formato 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