Вопрос: Преобразование строки в дату и время
Короткие и простые. У меня есть огромный список дат, таких как строки:
Jun 1 2005 1:33PM
Aug 28 1999 12:00AM
Я собираюсь вернуть их обратно в правильные поля datetime в базе данных, поэтому мне нужно магия их на реальные объекты datetime.
Любая помощь (даже если это просто удар в правильном направлении) будет оценена по достоинству.
Edit: Это происходит через ORM Django, поэтому я не могу использовать SQL для преобразования в insert.
1428
2018-01-21 18:00
источник
Ответы:
datetime.strptime
является основной процедурой для разбора строк в datetimes. Он может обрабатывать всевозможные форматы, формат которых определяется строкой формата, которую вы даете:
from datetime import datetime
datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
Результирующий datetime
объект является наименее часовым.
Ссылки:
Заметки:
strptime
= "время разбора строки" strftime
= "время форматирования строки" - Произносите его вслух сегодня, и вам не придется искать его снова через 6 месяцев.
2327
2018-01-21 18:08
Использовать третью сторону dateutil библиотека:
from dateutil import parser
dt = parser.parse("Aug 28 1999 12:00AM")
Он может обрабатывать большинство форматов даты, в том числе тот, который вам нужно проанализировать. Это более удобно, чем strptime, поскольку он может угадывать правильный формат большую часть времени.
Это очень полезно для написания тестов, где читаемость важнее производительности.
Вы можете установить его с помощью:
pip install python-dateutil
606
2018-01-22 18:27
Проверять, выписываться strptime в время модуль. Это инверсия 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)
458
2018-01-21 18:07
Я собрал проект, который может преобразовать некоторые действительно аккуратные выражения. Проверять, выписываться TimeString ,
Вот несколько примеров ниже:
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))
87
2018-03-02 14:22
У многих временных меток есть предполагаемый часовой пояс. Чтобы ваш код работал в каждом часовом поясе, вы должны использовать UTC внутри себя и присоединять часовой пояс каждый раз, когда посторонний объект входит в систему.
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)))
30
2018-03-06 11:53
Remember this and you didn't need to get confused in datetime conversion again.
String to datetime object = strptime
datetime object to other formats = strftime
Jun 1 2005 1:33PM
is equals to
%b %d %Y %I:%M%p
%b Month as locale’s abbreviated name(Jun)
%d Day of the month as a zero-padded decimal number(1)
%Y Year with century as a decimal number(2015)
%I Hour (12-hour clock) as a zero-padded decimal number(01)
%M Minute as a zero-padded decimal number(33)
%p Locale’s equivalent of either AM or PM(PM)
so you need strptime i-e converting string
to
>>> 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
...
Output
<type 'datetime.datetime'>
2005-06-01 13:33:00
<type 'datetime.datetime'>
1999-08-28 00:00:00
What if you have different format of dates you can use panda or 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]
OutPut
[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)]
30
2017-12-10 13:00
Something that isn't mentioned here and is useful: adding a suffix to the day. I decoupled the suffix logic so you can use it for any number you like, not just 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"))
21
2017-10-14 00:13
Here are two solutions using Pandas to convert dates formatted as strings into datetime.date objects.
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
And here is how to convert the OP's original date-time examples:
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)]
There are many options for converting from the strings to Pandas Timestamps using to_datetime
, so check the docs if you need anything special.
Likewise, Timestamps have many properties and methods that can be accessed in addition to .date
19
2017-12-20 03:03
Django Timezone aware datetime object example.
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)
This conversion is very important for Django and Python when you have USE_TZ = True
:
RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
12
2017-11-20 17:58
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
11
2018-01-19 07:48