Conversia șir în datetime

Am'am o listă foarte mare de data-ori asta, ca siruri de caractere:

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

Am'm de gând să fie impingandu-le înapoi în buna datetime câmpuri într-o bază de date, așa că am nevoie să-magic-le în adevărate datetime obiecte.

Acest lucru se întâmplă prin Django's ORM deci nu pot't de a folosi SQL pentru a face conversia de pe inserare.

Comentarii la întrebare (2)
Soluția

datetime.strptime este principalul rutină pentru parsarea siruri de caractere în datetimes. Se poate manipula tot felul de formate, cu formatul stabilit de către un șir format-ai dat-o:

from datetime import datetime

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

Rezultat "datetime" obiectul este în zona de fus orar-naiv.

Link-uri:

  • Python documentația pentru strptime`: Python 2, Python 3

  • Python documentația pentru strptime/strftime` format siruri de caractere: Python 2, Python 3

  • strftime.org este, de asemenea, un foarte frumos de referință pentru strftime

Note:

  • strptime = "string analiza timp"
  • strftime = "string format"
  • Se pronunță cu voce tare astăzi & ai câștigat't au pentru a căuta din nou în 6 luni.
Comentarii (14)

Folosi terțe părți dateutil biblioteca:

from dateutil import parser
parser.parse("Aug 28 1999 12:00AM")  # datetime.datetime(1999, 8, 28, 0, 0)

Se poate ocupa de cele mai multe formate de dată, inclusiv cea de care ai nevoie pentru a analiza. L's mai convenabil decât strptime cum se poate ghici corect format de cele mai multe ori.

L's foarte util pentru scrierea de teste, unde lizibilitatea este mai importantă decât performanța.

Îl puteți instala cu:

pip install python-dateutil
Comentarii (8)

Check out strptime timp modulul. Este inversul 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)
Comentarii (6)

Am pus împreună un proiect care poate converti unele foarte elegant expresii. Check out timestring.

Aici sunt câteva exemple de mai jos:

pip instala timestring

>>> import timestring
>>> timestring.Date('monday, aug 15th 2015 at 8:40 pm')

>>> timestring.Date('monday, aug 15th 2015 at 8:40 pm').date
datetime.datetime(2015, 8, 15, 20, 40)
>>> timestring.Range('next week')

>>> (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))
Comentarii (11)

Amintiți-vă acest lucru și nu te-ai't nevoie pentru a obține confuz în datetime de conversie din nou.

Șir la obiect datetime = strptime

datetime obiect în alte formate = strftime

Jun 1 2005 1:33PM

este egal cu

%b %d %F %I:%M%p

%b Luna ca localizare e numele abreviat(Iunie)

%d-a Zi a lunii ca un zero căptușit număr zecimal(1)

%Y An, cu lea ca număr zecimal(2015)

%I Oră (12 ore) ca un zero căptușit număr zecimal(01)

%M Minut ca un zero căptușit număr zecimal(33)

%p Locale echivalent, fie de AM sau PM(PM)

deci, ai nevoie strptime mi-e de conversie "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
... 

Ieșire


2005-06-01 13:33:00

1999-08-28 00:00:00

Ce se întâmplă dacă ai avea alt format de date puteți folosi panda sau dateutil.analiza

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

Ieșire

[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)]
Comentarii (2)

Multe amprente de timp au un implicite de fus orar. Pentru a se asigura că codul va funcționa în fiecare fus orar, ar trebui să utilizați UTC intern și atașați un orar de fiecare dată când un obiect străin intră în sistem.

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)))
Comentarii (1)

În Python >= 3.7.0,

pentru a converti AAAA-LL-ZZ șir la obiect datetime, datetime.fromisoformat ar putea fi folosit.

>>> from datetime import datetime

>>> date_string = "2012-12-12 10:10:10"
>>> print (datetime.fromisoformat(date_string))
>>> 2012-12-12 10:10:10
Comentarii (0)

Aici sunt două soluții folosind Panda pentru a converti datele formatate ca siruri de caractere într-datetime.data obiecte.

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

Programarea

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

Și aici este cum de a converti OP's original data-timp exemple:

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

Există mai multe opțiuni pentru conversia de la siruri de caractere pentru a Panda Marcajele de timp folosind to_datetime, deci, a verifica documente dacă ai nevoie de ceva special.

De asemenea, Marcajele de timp au multe proprietăți și metode, care pot fi accesate în plus față .data

Comentarii (0)

Ceva care nu e't menționat aici și este util: adăugarea unui sufix la zi. Am decuplat sufixul logică astfel încât să puteți folosi pentru orice număr doriți, nu doar datele.


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 
Comentarii (0)

Eu, personal, ca soluție, folosind parser modul, care este cel de-al doilea, Răspunsul la această întrebare este frumos, ca nu - 't au de a construi orice șir de caractere literale a obține de lucru. DAR, un dezavantaj este faptul că este 90% mai lent decât răspunsul acceptat cu 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

Atâta timp cât nu sunt a face acest lucru un milion de ori de peste si peste din nou, eu încă mai cred parser metodă este mult mai convenabil și se va ocupa de cele mai multe formate de timp în mod automat.

Comentarii (0)

Django fusul Orar conștienți obiect datetime exemplu.

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)

Această conversie este foarte important pentru Django Python și când ai USE_TZ = True`:

RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
Comentarii (1)
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
Comentarii (0)

A crea o mică funcție de utilitate, cum ar fi:

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

Acest lucru este destul de versatil:

  • Dacă tu nu't trece orice argumente se va reveni azi's date.
  • Nu's un format de dată implicit că puteți suprascrie.
  • Puteți modifica cu ușurință pentru a reveni un datetime.
Comentarii (1)

săgeată oferă multe funcții utile pentru date și ore. Acest cod oferă un răspuns la întrebare și arată că săgeata este, de asemenea, capabil de formatare datele cu ușurință și afișarea de informații pentru alte locații.

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

Vezi http://arrow.readthedocs.io/en/latest/ pentru mai multe.

Comentarii (0)

Ar fi util pentru conversia șir să datetime și, de asemenea, cu fusul orar

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)
Comentarii (0)

Puteți utiliza easy_date pentru a face mai ușor:

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

Dacă doriți doar formatul datei apoi, puteți converti manual prin trecerea câmpuri individuale, cum ar fi:

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

Puteți trece split șir de valori pentru a converti în data de tip, cum ar fi:

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

Veți obține valoarea rezultată în format dată.

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

se arată "Data de începere Data" Coloana și "Ultima Logare Timp" ambele sunt "obiect = siruri de caractere" în date-cadru


RangeIndex: 1000 entries, 0 to 999
Data columns (total 8 columns):
First Name           933 non-null object
Gender               855 non-null object

Data de începere 1000 non-null object

Ultima Conectare Ora 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

Prin utilizarea parse_dates "opțiune în" read_csv menționa puteți converti șirul datetime panda în format datetime.

emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv", parse_dates=["Start Date", "Last Login Time"])
emp.info()


RangeIndex: 1000 entries, 0 to 999
Data columns (total 8 columns):
First Name           933 non-null object
Gender               855 non-null object

Data de începere 1000 non-null datetime64[ns] Ultima Conectare Ora 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
Comentarii (0)

A se vedea mea answer.

În lumea reală, de date aceasta este o problemă reală: mai multe, nepotrivite, incomplete, inconsistente și mai multe limbi/regiune data formate, de multe ori amestecate în mod liber într-un singur set de date. L's nu este ok pentru producția de cod pentru a reuși, să nu mai vorbim excepție-fericit ca o vulpe.

Avem nevoie pentru a încerca...prinde mai multe datetime formate fmt1,fmt2,...,fmtn și de a suprima/ocupa excepții (de la strptime()) pentru toți cei care nepotrivire (și, în special, pentru a evita nevoie de un amărâte n-adânc crestate scara de try..catch clauze). De mea solution

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
Comentarii (5)