python today Convertir cadena en fecha y hora




python today date (16)

Corto y sencillo. Tengo una enorme 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 apropiados 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.


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)

Personalmente, me gusta la solución utilizando el módulo de parser , que es la segunda respuesta a esta pregunta y es hermosa, ya que no tienes que construir ningún literal de cadena para que funcione. Sin embargo, un inconveniente es que es 90% más lento que la respuesta aceptada con strptime respuesta.

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 lo haga un millón de veces una y otra vez, sigo pensando que el método del parser es más conveniente y manejará la mayoría de los formatos de tiempo automáticamente.


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

Utilice la biblioteca de dateutil terceros:

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

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

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.

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

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

Ejemplo de objeto datetime 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.

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.


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.


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 rellenado 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 rellenado con cero (33)

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

por lo que necesita strptime es decir, convertir la 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)]

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 de cadenas a to_datetime tiempo de Pandas usando to_datetime , así que verifique los docs si necesita algo especial.

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


Mira mi respuesta

En datos reales, este es un problema real: formatos de fecha múltiples, no coincidentes, incompletos, inconsistentes y multilenguaje / región, que a menudo se mezclan libremente en un conjunto de datos. No está bien que el código de producción falle, y mucho menos que salga feliz como un zorro.

Necesitamos probar ... capturar múltiples formatos de fecha y hora fmt1, fmt2, ..., fmtn y suprimir / manejar las excepciones (de strptime() ) para todos aquellos que no coincidan (y en particular, evitar la necesidad de un yukky n-deep sangrado Escalera de intencion ... cláusulas de captura). De mi solucion

def try_strptime(s, fmts=['%d-%b-%y','%m/%d/%Y']):
    for fmt in fmts:
        try:
            return datetime.strptime(s, fmt)
        except:
            continue

    return None # or reraise the ValueError if no format matched, if you prefer

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

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"))​​​​​​​

He reunido un proyecto que puede convertir algunas expresiones realmente limpias. Echa un vistazo a timestring .

Aquí hay algunos ejemplos a continuación:

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




datetime