Преобразование строки в дату и время

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

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

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

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

Ответы

Ответ 1

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

from datetime import 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 строк strptime/strftime: Python 2, Python 3

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

Заметки:

  • strptime= "время разбора строки"
  • strftime= "string format time"
  • Произносите его вслух сегодня, и вам не придется искать его снова через 6 месяцев.

Ответ 2

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

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

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

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

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

pip install python-dateutil

Ответ 3

Отметьте strptime в time. Это инверсия 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)

Ответ 4

Я собрал проект, который может преобразовать некоторые действительно аккуратные выражения. Проверьте 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))

Ответ 5

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

String to datetime object = strptime

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

Jun 1 2005 1:33PM

равно

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

% b Месяц по сокращенному имени локалей (июнь)

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

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

% я Час (12-часовые часы) в виде десятичного числа с нулевой задержкой (01)

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

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

так что вам нужно преобразовать i-e 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)]

Ответ 6

У многих временных меток есть подразумеваемый часовой пояс. Чтобы ваш код работал в каждом часовом поясе, вы должны использовать 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)))

Ответ 7

Вот два решения, использующие 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

А вот как конвертировать оригинальные примеры даты и времени в 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)]

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

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

Ответ 8

В Python> = 3.7.0,

чтобы преобразовать строку ГГГГ-ММ-ДД в объект datetime.fromisoformat можно использовать 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

Ответ 9

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

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

Ответ 10

Мне лично нравится решение, использующее модуль 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 более удобен и будет обрабатывать большинство форматов времени автоматически.

Ответ 11

Пример события 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)

Это преобразование очень важно для 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.

Ответ 12

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

Ответ 13

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

from datetime import datetime

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

Ответ 14

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

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

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

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

Ответ 15

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

import datetime

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

Ответ 16

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

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

См. Http://arrow.readthedocs.io/en/latest/ для получения дополнительной информации.

Ответ 17

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

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)

Ответ 18

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

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

Ответ 19

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

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

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

Ответ 20

(ММ ДД ГГГГ ЧЧ: ММ) Формат

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

Ответ 21

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 в формат панд даты и времени.

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

Ответ 22

Вы также можете использовать утенка Facebook.

Попробуйте это онлайн здесь: https://duckling.wit.ai/

Для библиотеки есть оболочка python: pip install duckling

Он поддерживает гораздо больше, чем только разбор времени.

Ответ 23

См. Мой ответ.

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

Нам нужно попытаться... уловить несколько форматов datetime fmt1, fmt2,..., fmtn и подавить/обработать исключения (из strptime()) для всех несоответствующих (и, в частности, избегать использования yukky n-deep indented лестница предложений 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