web-dev-qa-db-ja.com

文字列を日時に変換する

短くてシンプル。私は文字列としてこのような日時の膨大なリストを持っています:

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

これらをデータベースの適切な日時フィールドに戻して入れようと思っているので、それらを実際の日時オブジェクトにマジックする必要があります。

(たとえそれが正しい方向へのキックであったとしても)どんな助けでも感謝されるでしょう。

編集:これはDjangoのORMを通過しているので、挿入時にSQLを使って変換することはできません。

1838
Oli

datetime.strptimeは、文字列を日時に解析するためのメインルーチンです。それはあなたがそれに与えるフォーマット文字列によって決定されるフォーマットで、あらゆる種類のフォーマットを扱うことができます:

from datetime import datetime

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

結果として得られるdatetimeオブジェクトはタイムゾーン固有です。

リンク集

  • strptimeに関するPythonのドキュメント: Python 2Python 3

  • strptime/strftimeフォーマット文字列のPythonドキュメント: Python 2Python 3

  • strftime.org もstrftimeのための本当に素晴らしい参照です。

ノート:

  • strptime = "文字列解析時間"
  • strftime = "文字列フォーマット時間"
  • 今日は大声で発音してください。6ヶ月以内にもう一度検索する必要はありません。
2933

サードパーティの dateutil libraryを使用してください。

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

解析する必要があるものも含め、ほとんどの日付フォーマットを処理できます。ほとんどの場合正しい形式を推測できるため、strptimeよりも便利です。

読みやすさがパフォーマンスよりも重要であるテストを書くのに非常に役に立ちます。

あなたはそれをインストールすることができます:

pip install python-dateutil
712
Simon Willison

time モジュールの 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)
470
florin

これを覚えていて、あなたは再び日時変換に混乱する必要はありません。

Datetimeオブジェクトへの文字列= strptime

他のフォーマットへのdatetimeオブジェクト= strftime

Jun 1 2005 1:33PM

と等しい

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

%bロケールの短縮名としての月(6月)

%dゼロ詰め10進数としての月の日(1)

世紀を10進数で表した%Y年(2015)

ゼロ詰め10進数(01)としての%I Hour(12時間制)

%Mゼロ詰め10進数としての分(33)

%pロケールがAMまたはPMのどちらかに相当する(PM)

だからあなたはstringをに変換するstrptime i-eが必要です

>>> 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)]
41
Rizwan Mumtaz

多くのタイムスタンプには暗黙のタイムゾーンがあります。コードがすべてのタイムゾーンで機能するようにするには、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)))
31
Janus Troelsen

これは、Pandasを使用して文字列としてフォーマットされた日付をdatetime.dateオブジェクトに変換する2つの解決策です。

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

to_datetimeを使用して文字列からPandasタイムスタンプに変換するための多くのオプションがありますので、何か特別なことが必要な場合は docs を確認してください。

同様に、タイムスタンプは.dateに加えてアクセスできる多くの プロパティとメソッド を持っています

23
Alexander

ここで言及されていないと便利です:その日に接尾辞を追加します。私はサフィックスロジックを切り離したので、日付だけでなく好きな番号に使うことができます。

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
Aram Kocharyan

個人的には、parserモジュールを使用したソリューションが気に入っています。これは、この質問に対する2番目の回答であり、機能するために文字列リテラルを作成する必要がないので美しいです。 BUT、マイナス面の1つは、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メソッドがより便利であり、処理すると思いますほとんどの時間は自動的にフォーマットされます。

21
user1767754

Djangoタイムゾーン対応datetimeオブジェクトの例.

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)

USE_TZ = Trueがある場合、この変換はDjangoとPythonにとって非常に重要です。

RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2016-03-04 00:00:00) while time zone support is active.
14
Ryu_hayabusa
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
12
guneysus

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')
12
Toskan

以下のような小さな効用関数を作成します。

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

これは十分に用途が広いです。

  • 引数を渡さないと、今日の日付が返されます。
  • あなたが上書きすることができるデフォルトとして日付フォーマットがあります。
  • あなたは簡単にそれを修正して日時を返すことができます。
9
Mackraken

Python> = 3.7.0では、

YYYY-MM-DD文字列をdatetimeオブジェクトに変換するには 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
SuperNova

datetime Pythonモジュールは、日付時刻の取得や日付時刻形式の変換に適しています。

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
8
Rajiv Sharma

arrow は日付と時刻に便利な関数をたくさん提供しています。このコードは質問に対する答えを提供し、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/ を参照してください。

7
Bill Bell

簡単にするために easy_date を使うことができます。

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

文字列を日時に変換したり、タイムゾーンを使ったりするのに役立ちます。

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)
4
Kanish Mathew

日付形式のみが必要な場合は、次のように個々のフィールドを渡して手動で変換できます。

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

結果の値は日付形式で得られます。

3
Javed

Facebookのアヒルの子を使うこともできます。

ここでそれをオンラインで試してください: https://duckling.wit.ai/ /

ライブラリ用の pythonラッパー があります。pip install duckling

時間解析だけではありません。

0
Domi W
emp = pd.read_csv("C:\\py\\programs\\pandas_2\\pandas\\employees.csv")
emp.info()

「開始日」列と「最終ログイン」列はどちらもデータフレーム内の「object = strings」です。

<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_datesread_csvオプションを使用することで、文字列のdatetimeをパンダの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
0
Riz.Khan