Преобразование строки в дату и время - PullRequest
1869 голосов
/ 21 января 2009

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

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

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

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

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

Ответы [ 19 ]

2980 голосов
/ 21 января 2009

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

from datetime import datetime

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

Полученный объект datetime является часовым поясом.

Ссылки:

Примечания:

  • strptime = "время разбора строки"
  • strftime = "время форматирования строки"
  • Произнесите это вслух сегодня, и вам не придется искать его снова через 6 месяцев.
724 голосов
/ 22 января 2009

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

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

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

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

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

pip install python-dateutil
473 голосов
/ 21 января 2009

Проверьте 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)
104 голосов
/ 02 марта 2014

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

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

Строка для объекта datetime = strptime

объект даты / времени в других форматах = 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 i-e преобразовать 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]

1041 Мощн * *

[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)]
31 голосов
/ 06 марта 2014

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

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

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"))​​​​​​​
23 голосов
/ 20 декабря 2015

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

19 голосов
/ 02 января 2018

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

14 голосов
/ 22 февраля 2019

В Python> = 3.7.0,

для преобразования строки ГГГГ-ММ-ДД в объект даты и времени , 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...