«огромный список ... база данных» просто подразумевает, что их много, а не то, что все они имеют разные форматы. Вполне допустимо писать код, который читает один формат, если вы знаете, что во входе есть один формат. В этом случае должно произойти сбой, если передается что-то, что не в правильном формате.

ко и просто. У меня есть огромный список дат, таких как строки:

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

Я собираюсь перенести их обратно в надлежащие поля даты и времени в базе данных, поэтому мне нужно преобразовать их в реальные объекты даты и времени.

Любая помощь (даже если это просто удар в правильном направлении) будет принята с благодарностью.

Изменить: Это проходит через ORM Django, поэтому я не могу использовать SQL для преобразования при вставке.

 Joshua Baboo22 апр. 2016 г., 21:38
для преобразования всего столбца со строками даты-значения ref в параметр, указанный вдругой пост
 smci15 дек. 2017 г., 04:00
Если вы не уверены, что один формат обрабатывает каждую дату-дату (нет '', нет NaN, нет неполных, нет несовпадений форматов, нет конечных символов, часовых поясов, меток времени в микросекундах или другого текста ...), счастье исключения -strptime() сводит вас с ума, если вы не оберните его. Смотрите мой ответ, основанный наИли Weis ответ на это

Ответы на вопрос(21)

и вам не нужно было снова путаться в преобразовании даты и времени.

String to datetime object =strptime

объект datetime в другие форматы =strftime

Jun 1 2005 1:33PM

равно

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

% b Месяц как сокращенное название локали (июнь)

% d День месяца в виде десятичного числа с нулем (1)

% Y Год с веком в виде десятичного числа (2015)

% I час (12-часовые часы) как десятичное число с нулем (01)

% M Минута как десятичное число с добавлением нуля (33)

% p Локальный эквивалент AM или PM (PM)

так что вам нужно strptime я-е преобразованиеstring в

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

Выход

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

Что если у вас другой формат дат, вы можете использовать panda или 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]

Выход

[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)]
 bfontaine08 мая 2018 г., 11:44
не будет%b перерыв, если вы анализируете английскую дату на машине, у которой нет английского языка?
 optimist09 июн. 2017 г., 07:42
% S для секунд в десятичном виде

добавление суффикса к дню. Я отделил суффиксную логику, чтобы вы могли использовать ее для любого числа, которое вам нравится, а не только для дат.

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

использующие Pandas для преобразования дат, отформатированных в виде строк, в объекты 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)]

Задержки

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

А вот как конвертировать оригинальные примеры даты и времени ОП:

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

Существует много вариантов преобразования строк в метки времени Pandas с использованиемto_datetimeтак что проверьтедокументы если вам нужно что-то особенное.

Аналогично, у Временных меток есть многосвойства и методы к которым можно получить доступ в дополнение к.date

Мне лично нравится решение с использованиемparser Модуль, который является вторым ответом на этот вопрос и красив, так как вам не нужно создавать строковые литералы, чтобы он работал.НООдин недостаток в том, что этоНа 90% медленнее чем принятый ответ с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

Пока ты этого не делаешьмиллион раз за разом, я все еще думаю, чтоparser Этот метод более удобен и автоматически обрабатывает большинство форматов времени.

стрелка предлагает много полезных функций для даты и времени. Этот фрагмент кода дает ответ на вопрос и показывает, что стрелка также способна легко форматировать даты и отображать информацию для других локалей.

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

Видетьhttp://arrow.readthedocs.io/en/latest/ для большего.

Вы можете использоватьeasy_date чтобы было проще:

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

мой ответ.

В реальных данных это реальная проблема: множественные, несовпадающие, неполные, несовместимые и мультиязычные / региональные форматы даты, часто свободно смешанные в одном наборе данных. Это не нормально для производственного кода, чтобы провалиться, не говоря уже о том, чтобы быть счастливым, как лиса.

Нам нужно попробовать ... поймать несколько форматов даты и времени fmt1, fmt2, ..., fmtn и подавить / обработать исключения (изstrptime()) для всех тех, кто не соответствует (и, в частности, избегать необходимости в юкки-n-глубокой лестнице с предложениями try..catch). Измое решение

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
 RoG03 окт. 2018 г., 09:28
«огромный список ... база данных» просто подразумевает, что их много, а не то, что все они имеют разные форматы. Вполне допустимо писать код, который читает один формат, если вы знаете, что во входе есть один формат. В этом случае должно произойти сбой, если передается что-то, что не в правильном формате.
 smci02 окт. 2018 г., 21:38
@RoG: никогда не говорилось, что они не были, и это подразумевало, что они были:"огромный список ... база данных", В большинстве каждой базы данных / файла журнала, над которым я работал (даже небольшого размера), было несколько форматов даты, идентификаторов часовых поясов, MM-DD и т. Д. В производстве недопустимо писать хрупкий код, который жестко кодирует в форматах и ​​вылетает, за исключением случаев, когда он не получает ожидаемый формат (даже возвращает None или '' более приемлемо). Отсюда необходимость в нескольких форматах. Следовательно, это отвечает на поставленный вопрос, и я потратил немного времени на то, чтобы выяснить наиболее питонский способ обработки ошибок из разных форматов.
 RoG02 окт. 2018 г., 14:28
В вопросе ничего не сказано о «множественных, несовпадающих, неполных, несовместимых и многоязычных / региональных форматах даты» и т. Д. Это может быть реальной проблемой, но не относящейся к делу.
Решение Вопроса

datetime.strptime является основной процедурой разбора строк в datetime. Он может обрабатывать все виды форматов, причем формат определяется строкой формата, которую вы ему задаете:


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

Результирующийdatetime объект является часовым поясом наивным.

Ссылки:

Python документация дляstrptime: Python 2, Python 3

Python документация дляstrptime/strftime формат строки:Python 2, Python 3

strftime.org также очень хорошая ссылка для strftime

Примечания:

strptime = "время разбора строки"strftime = "время форматирования строки"Произнесите это вслух сегодня, и вам не придется искать его снова через 6 месяцев.
 jononomo28 апр. 2014 г., 21:07
почему это возвращает date_object, а не datetime_object?
 Martin Thoma07 дек. 2017 г., 14:56
Я искал"%Y-%m-%d %H:%M:%S"
 jfs29 апр. 2014 г., 12:55
"% b", "% p" может завершиться с ошибкой в ​​неанглийской локали.
 Izkata11 нояб. 2014 г., 21:02
@User Вы должны знать заранее, чтобы исключить эту часть строки формата, но если вы хотитеdate вместоdatetime, пройдя черезdatetime справляется с этим красиво:datetime.strptime('Jun 1 2005', '%b %d %Y').date() == date(2005, 6, 1)
 Flimm08 дек. 2016 г., 11:28
Если вы знаете, что строка представляет дату и время в формате UTC, вы можете узнать о часовом поясеdatetime возразить, добавив эту строку в Python 3:from datetime import timezone; datetime_object = datetime_object.replace(tzinfo=timezone.utc)

для преобразованияГГГГ-ММ-ДД строка для объекта даты и времени, 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

Пример объекта даты / времени с поддержкой Django.

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)

Это преобразование очень важно для Django и Python, когда у вас естьUSE_TZ = True:

RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
 shadi10 сент. 2018 г., 06:09
Так что ваша точка зрения заключается в использованииtz.localize?
emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")
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 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

Используяparse_dates вариант вread_csv Отметим, что вы можете преобразовать вашу строку datetime в pandas datetime format.

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

а также с часовым поясом

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)
 Harry Moreno29 авг. 2018 г., 21:59
Мне нужна строка даты и времени с часовым поясом

Проверять, выписываться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)
 jfs29 апр. 2014 г., 12:54
@BenBlank: «% b», «% p» может не работать в неанглийской локали.
 ᴠɪɴᴄᴇɴᴛ22 окт. 2014 г., 14:07
@ hobbes3parse а такжеformat.
 Alexander Bird07 сент. 2010 г., 15:08
Из того, что я понимаю, этот ответ выводит только объекты времени, а не объекты даты и времени - вот почему ответ будет похоронен по сравнению с ответом Патрика.
 Anatoly G19 июн. 2011 г., 21:56
ответ ниже (Патрик Харрингтон) является более правильным, потому что time.strptime выводит только время, а не datetime
 Leandro Alves09 мар. 2013 г., 16:20
Как сказал Александр, это возвращает struct_time, а не datetime. Конечно, вы можете преобразовать его в дату и время, но ответ Патрика будет более прямым, если вам нужен объект даты и времени в конце.

Создайте небольшую служебную функцию, например:

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

Это достаточно универсально:

Если вы не передадите никаких аргументов, он вернет сегодняшнюю дату.По умолчанию есть формат даты, который вы можете переопределить.Вы можете легко изменить его, чтобы вернуть дату и время.
 shredding10 янв. 2017 г., 10:30
format является зарезервированным словом в python и не должен использоваться в качестве имени переменной.

од работал в каждом часовом поясе, вы должны использовать 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)))
 jfs14 сент. 2014 г., 19:36
Почему вы держите некрасивых и порой ошибочных (mktime() во время переходов DST) 1-й метод, если вы знаете 2-й метод (datetime.strptime())? Если вы хотите избежать исключения в течение високосной секунды (2-й метод не работает), вы можете использоватьcalendar.timegm вместо:(datetime(1970,1,1)+timedelta(seconds=timegm(time.strptime(..)))).replace(tzinfo=timezone(timedelta(-3)))

Дата и время Модуль Python хорош для получения даты и времени и преобразования форматов даты и времени.


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

Выход:

2005-06-01 13:33:00
2005/06/01 01:33PM
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

Используйте третье лицоdateutil библиотека:

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

Он может обрабатывать большинство форматов дат, включая тот, который вам нужен для анализа. Это более удобно, чем strptime, так как большую часть времени он может угадать правильный формат.

Это очень полезно для написания тестов, где удобочитаемость важнее производительности.

Вы можете установить его с помощью:

pip install python-dateutil
 Antony Hatchkins30 апр. 2013 г., 20:19
@Reef: в 5 раз медленнее, в соответствии с моим быстрым и грязным тестом. Нетак ужасно медленно, как я и ожидал.
 Kartik Domadiya06 мар. 2013 г., 07:11
Когда я пытаюсь разобрать "32-й Ян", он возвращает мне "2032-01-06" .. что неверно. есть ли способ проверить, является ли строка действительной датой или нет
 brian buck12 окт. 2011 г., 22:33
Это хорошо, но было бы неплохо иметь встроенное решение, а не обращаться к третьей стороне.
 Paweł Polewicz03 июл. 2011 г., 02:08
Помните, что для больших объемов данных это может быть не самым оптимальным способом решения проблемы. Угадывание формата каждый раз может быть ужасно медленным.
 F1Rumors18 мая 2015 г., 17:42
У него есть свои проблемы, такие как, например, автоматическое удаление информации о часовом поясе из времен: попробуйте parser.parse ('15: 55EST ') и сравните с parser.parse ('15 .55CST') в качестве примера.

вы можете вручную конвертировать его, передавая отдельные поля, например:

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

Вы можете передать значения разделенной строки, чтобы преобразовать их в тип даты, например:

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

Вы получите полученное значение в формате даты.

который может конвертировать некоторые действительно аккуратные выражения. Проверять, выписываться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))
 Steve Peak14 апр. 2014 г., 16:30
Добро пожаловать. Буду рад вашим комментариям и идеям по улучшению этого пакета. Дайте мне знать, используйте вопросы GitHub. Спасибо!
 arctelix22 окт. 2014 г., 21:58
@Steve Peak timestring отлично работает! Нужно было разобрать даты статей со скрапами, и это отлично их преобразовало.
 Anake23 окт. 2014 г., 12:00
Привет Стив, модуль отличный. Было бы неплохо иметь атрибут строки дня недели. В противном случае не уверен, если вы начинаете с понедельника или воскресенья
 brandonjp11 апр. 2014 г., 07:09
Ух ты. Ух ты. Ух ты. Ух ты. Это так просто. У меня есть строка даты и времени, и я просто хочу вытащить год. Так просто как:import timestring timestring.Date('27 Mar 2014 12:32:29 GMT').year Эта библиотека сделала это так легко! Спасибо.
 Steve Peak26 окт. 2014 г., 00:22
@ Anake, вы можете создать проблему, чтобы запросить это добавлено вgithub.com/stevepeak/timestring Спасибо!

для формата unix / mysql 2018-10-15 20:59:29


datetime_object = datetime.strptime('2018-10-15 20:59:29', '%Y-%m-%d %H:%M:%S')

Ваш ответ на вопрос