Konwertowanie łańcucha do datetime
Mam ogromną listę dat-czasów takich jak ten jako ciągi:
Jun 1 2005 1:33PM
Aug 28 1999 12:00AM
Zamierzam wepchnąć je z powrotem do odpowiednich pól datetime w bazie danych, więc muszę zaczarować je w prawdziwe obiekty datetime.
To przechodzi przez ORM Django, więc nie mogę użyć SQL do konwersji na insert.
22 answers
datetime.strptime
jest główną rutyną do parsowania łańcuchów do dat. Może obsługiwać wszystkie rodzaje formatów, z formatem określonym przez ciąg formatów, który mu podasz:
from datetime import datetime
datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
Wynikowy obiekt datetime
nie ma strefy czasowej.
Linki:
Dokumentacja Pythona dla
strptime
/strftime
ciągi formatujące: Python 2, Python 3-
Strftime.org jest również bardzo dobrym odniesieniem do strftime
Uwagi:
-
strptime
= "string parse time" -
strftime
= "string format time" - Wymów go na głos dzisiaj i nie będziesz musiał szukać go ponownie w ciągu 6 miesięcy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-28 06:17:54
Użyj trzeciej strony dateutil biblioteka:
from dateutil import parser
parser.parse("Aug 28 1999 12:00AM") # datetime.datetime(1999, 8, 28, 0, 0)
Może obsługiwać większość formatów dat, w tym ten, który musisz przeanalizować. Jest to wygodniejsze niż strptime
, ponieważ potrafi odgadnąć poprawny format przez większość czasu.
Jest bardzo przydatny do pisania testów, gdzie czytelność jest ważniejsza niż wydajność.
Można go zainstalować za pomocą:
pip install python-dateutil
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-08 23:20:42
Sprawdź strptime w moduletime . Jest odwrotnością strftime .
$ python
>>> import time
>>> my_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)
timestamp = time.mktime(my_time)
# convert time object to datetime
from datetime import datetime
my_datetime = datetime.fromtimestamp(timestamp)
# convert time object to date
from datetime import date
my_date = date.fromtimestamp(timestamp)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-07 22:11:43
Przygotowałem projekt, który potrafi konwertować naprawdę fajne wyrażenia. Zobacz też timestring.
Oto kilka przykładów poniżej:
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))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Python > = 3.7
Aby przekonwertować RRRR-MM-DD string na obiekt datetime, można użyć datetime.fromisoformat
.
>>> from datetime import datetime
>>> date_string = "2012-12-12 10:10:10"
>>> print (datetime.fromisoformat(date_string))
>>> 2012-12-12 10:10:10
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-24 08:45:39
Pamiętaj o tym i nie musisz się ponownie mylić w konwersji datetime.
String to datetime object = strptime
Obiekt Datetime do innych formatów = strftime
Jun 1 2005 1:33PM
Jest równe
%b %d %Y %I:%M%p
% B miesiąc jako skrócona nazwa locale (Jun)
%D dnia miesiąca jako liczba dziesiętna (1)
%rok z wiekiem jako liczbą dziesiętną(2015)
%i godzina (Zegar 12-godzinny) jako liczba dziesiętna zerowa (01)
% m minuta jako liczba dziesiętna (33)
% P odpowiednik lokalnego AM lub PM (PM)
Więc potrzebujesz konwersji strptime i-E string
na
>>> 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
...
Wyjście
<type 'datetime.datetime'>
2005-06-01 13:33:00
<type 'datetime.datetime'>
1999-08-28 00:00:00
Co jeśli masz inny format dat, możesz użyć panda lub 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]
Wyjście
[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)]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-30 07:20:19
Wiele znaczników czasu ma domyślną strefę czasową. Aby mieć pewność, że Twój kod będzie działał w każdej strefie czasowej, powinieneś użyć UTC wewnętrznie i dołączyć strefę czasową za każdym razem, gdy obcy obiekt wejdzie do systemu.
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)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-05 12:34:58
Oto dwa rozwiązania wykorzystujące pandy do konwersji dat sformatowanych jako ciągi znaków na datetime.obiekty daty.
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
A oto jak przekonwertować oryginalne przykłady daty i czasu 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)]
Istnieje wiele opcji konwersji z łańcuchów na znaczniki czasu Pandy za pomocą to_datetime
, więc sprawdź docs jeśli potrzebujesz czegoś specjalnego.
Podobnie znaczniki czasu mają wiele właściwości i metod , które można uzyskać w dodatek do .date
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-02 07:08:49
Osobiście podoba mi się rozwiązanie za pomocą modułu parser
, który jest drugą odpowiedzią na to pytanie i jest piękny, ponieważ nie trzeba konstruować żadnych liter ciągów, aby to działało. ale , jednym minusem jest to, że jest ona 90% wolniejsza niż przyjęta odpowiedź z 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
Dopóki nie robisz tego milion razy w kółko, nadal uważam, że metoda parser
jest wygodniejsza i obsłuży większość formatów czasu automatycznie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-01 01:50:18
Coś, co nie jest tutaj wymienione i jest przydatne: dodanie sufiksu do dnia. Oddzieliłem logikę przyrostka, żebyś mógł go używać dla dowolnej liczby, nie tylko dat.
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"))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-14 00:28:40
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-19 07:48:47
Django timezone aware DateTime object przykład.
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)
Ta konwersja jest bardzo ważna dla Django i Pythona, gdy masz USE_TZ = True
:
RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 13:44:40
Przydałby się do konwersji łańcucha znaków do datetime, a także ze strefą czasową
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-30 05:49:20
Tworzenie małej funkcji użytkowej jak:
def date(datestr="", format="%Y-%m-%d"):
from datetime import datetime
if not datestr:
return datetime.today().date()
return datetime.strptime(datestr, format).date()
To jest wystarczająco uniwersalne:
- Jeśli nie podasz żadnych argumentów, zwróci dzisiejszą datę.
- istnieje domyślny format daty, który możesz zastąpić.
- można go łatwo zmodyfikować, aby zwrócić datetime.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 23:00:23
Arrow oferuje wiele przydatnych funkcji dla dat i godzin. Ten fragment kodu zapewnia odpowiedź na pytanie i pokazuje, że arrow jest również w stanie łatwo formatować daty i wyświetlać informacje dla innych lokalizacji.
>>> 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'
Zobacz http://arrow.readthedocs.io/en/latest / Po Więcej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 23:02:32
Możesz użyć easy_date aby to ułatwić:
import date_converter
converted_date = date_converter.string_to_datetime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-01 15:15:02
Jeśli chcesz tylko format daty, możesz ręcznie przekonwertować go, przekazując poszczególne pola, takie jak:
>>> import datetime
>>> date = datetime.date(int('2017'),int('12'),int('21'))
>>> date
datetime.date(2017, 12, 21)
>>> type(date)
<type 'datetime.date'>
Możesz przekazać podzieloną wartość łańcuchową, aby przekonwertować ją na typ daty, taki jak:
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]))
Uzyskasz wartość w formacie daty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 23:04:32
Możesz również sprawdzić dateparser
dateparser
dostarcza moduły do łatwego analizowania zlokalizowanych dat w prawie wszelkie formaty ciągów powszechnie spotykane na stronach internetowych.
zainstaluj:
$ pip install dateparser
To chyba najprostszy sposób na analizę dat.
Najprostszym sposobem jest użycie funkcji
dateparser.parse
, to owija się wokół większości funkcji w module.
próbka Kod:
import dateparser
t1 = 'Jun 1 2005 1:33PM'
t2 = 'Aug 28 1999 12:00AM'
dt1 = dateparser.parse(t1)
dt2 = dateparser.parse(t2)
print(dt1)
print(dt2)
Wyjście:
2005-06-01 13:33:00
1999-08-28 00:00:00
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-12 17:55:16
Jeśli twój ciąg znaków jest w formacie ISO8601 i masz Pythona 3.7+, możesz użyć następującego prostego kodu:
import datetime.date
aDate = datetime.date.fromisoformat('2020-10-04')
Dla dat i
import datetime.datetime
aDateTime = datetime.datetime.fromisoformat('2020-10-04 22:47:00')
Dla łańcuchów zawierających datę i czas. Jeśli znaczniki czasu są włączone, funkcja datetime.datetime.isoformat()
obsługuje następujący format
YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]
Gdzie *
pasuje do dowolnego pojedynczego znaku. Zobacz także tutaj i tutaj
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-04 20:57:05
Zobacz moja odpowiedź .
W rzeczywistych danych jest to prawdziwy problem: wiele, niedopasowanych, niekompletnych, niespójnych i wielojęzycznych/regionalnych formatów dat, często mieszanych swobodnie w jednym zbiorze danych. Nie jest w porządku, żeby kod produkcyjny zawodził, nie mówiąc już o wyjątkach-szczęśliwy jak lis.
Musimy spróbować...przechwytywanie wielu formatów datetime fmt1, fmt2,..., fmtn i tłumią/obsługują wyjątki (odstrptime()
) dla wszystkich tych, które nie pasują (a w szczególności unikają konieczności wcięta drabina próby..klauzule połowu). Z moje rozwiązanie
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-05 15:52:25
emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")
emp.info()
Pokazuje kolumnę " Data rozpoczęcia czasu "i" czas ostatniego logowania "obie są" obiekt = ciągi " w ramce danych
<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
Za pomocą parse_dates
opcja w read_csv
wspomnieć można przekonwertować swój łańcuch datetime do formatu datetime pandy.
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-01 12:17:51
Wydaje się, że użycie znacznika czasu pandas jest najszybsze
import pandas as pd
N = 1000
l = ['Jun 1 2005 1:33PM'] * N
list(pd.to_datetime(l, format=format))
%timeit _ = list(pd.to_datetime(l, format=format))
1.58 ms ± 21.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Inne rozwiązania
from datetime import datetime
%timeit _ = list(map(lambda x: datetime.strptime(x, format), l))
9.41 ms ± 95.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
from dateutil.parser import parse
%timeit _ = list(map(lambda x: parse(x), l))
73.8 ms ± 1.14 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Jeśli ciąg jest iso8601 string Proszę użyć csio8601
import ciso8601
l = ['2014-01-09'] * N
%timeit _ = list(map(lambda x: ciso8601.parse_datetime(x), l))
186 µs ± 4.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-29 07:09:40