サーチ…


備考

Pythonは、日付と時刻を作成、変更、解析、操作するための組み込みメソッドと外部ライブラリの両方を提供します。

文字列をタイムゾーン対応のdatetimeオブジェクトに解析する

文字列datetimeオブジェクトに解析するとき、Python 3.2以降では%z形式をサポートしています。

+HHMMまたは-HHMM形式のUTCオフセット(オブジェクトがナイーブな場合は空文字列)。

Python 3.x 3.2
import datetime
dt = datetime.datetime.strptime("2016-04-15T08:27:18-0500", "%Y-%m-%dT%H:%M:%S%z")

Pythonの他のバージョンでは、 dateutilような外部ライブラリを使うことができます。これは、タイムゾーン付きの文字列を解析してdatetimeオブジェクトにすることを素早く行います。

import dateutil.parser
dt = dateutil.parser.parse("2016-04-15T08:27:18-0500")

dt変数は、次の値を持つdatetimeオブジェクトになりました。

datetime.datetime(2016, 4, 15, 8, 27, 18, tzinfo=tzoffset(None, -18000))

簡単な日付演算

日付は孤立して存在しません。あなたは、日付の間の時間の量を見つけるか、または日付が明日になるかを決定する必要があるのが一般的です。これはtimedeltaオブジェクトを使用してtimedeltaできます

import datetime

today = datetime.date.today()
print('Today:', today)

yesterday = today - datetime.timedelta(days=1)
print('Yesterday:', yesterday)

tomorrow = today + datetime.timedelta(days=1)
print('Tomorrow:', tomorrow)

print('Time between tomorrow and yesterday:', tomorrow - yesterday)

これにより、次のような結果が得られます。

Today: 2016-04-15
Yesterday: 2016-04-14
Tomorrow: 2016-04-16
Difference between tomorrow and yesterday: 2 days, 0:00:00

基本的なdatetimeオブジェクトの使用

datetimeモジュールには、日付、時刻、日付時刻の3つの主な種類のオブジェクトが含まれています。

import datetime

# Date object
today = datetime.date.today()
new_year = datetime.date(2017, 01, 01) #datetime.date(2017, 1, 1)

# Time object
noon = datetime.time(12, 0, 0) #datetime.time(12, 0)

# Current datetime
now = datetime.datetime.now()

# Datetime object
millenium_turn = datetime.datetime(2000, 1, 1, 0, 0, 0) #datetime.datetime(2000, 1, 1, 0, 0)

これらのオブジェクトの算術演算は、同じデータ型内でのみサポートされ、異なる型のインスタンスで簡単な算術演算を実行すると、TypeErrorが発生します。

# subtraction of noon from today
noon-today
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.date'
However, it is straightforward to convert between types.

# Do this instead
print('Time since the millenium at midnight: ',
      datetime.datetime(today.year, today.month, today.day) - millenium_turn)

# Or this
print('Time since the millenium at noon: ',
      datetime.datetime.combine(today, noon) - millenium_turn)

日付を反復する

時には、開始日から終了日までのある範囲の日付にわたって繰り返したいと思うことがあります。あなたはdatetimeライブラリとtimedeltaオブジェクトを使用してそれを行うことができます:

import datetime

# The size of each step in days
day_delta = datetime.timedelta(days=1)

start_date = datetime.date.today()
end_date = start_date + 7*day_delta

for i in range((end_date - start_date).days):
    print(start_date + i*day_delta)

生成するもの:

2016-07-21
2016-07-22
2016-07-23
2016-07-24
2016-07-25
2016-07-26
2016-07-27

短いタイムゾーン名を持つ文字列をタイムゾーン対応のdatetimeオブジェクトに解析する

前の例のようにdateutilライブラリを使用してタイムゾーン対応のタイムスタンプを解析すると、指定された「短い」タイムゾーン名でタイムスタンプを解析することもできます。

一般的にあいまいな短い時間帯の名前または略語でフォーマットされた日付の場合(たとえば中部標準時、中国標準時、キューバ標準時などのCSTなど - 詳細はこちら )、標準データベースでは必ずしも入手できないタイムゾーン省略形とtzinfoオブジェクトの間のマッピングを指定する必要があります。

from dateutil import tz
from dateutil.parser import parse

ET = tz.gettz('US/Eastern')
CT = tz.gettz('US/Central')
MT = tz.gettz('US/Mountain')
PT = tz.gettz('US/Pacific')

us_tzinfos = {'CST': CT, 'CDT': CT,
              'EST': ET, 'EDT': ET,
              'MST': MT, 'MDT': MT,
              'PST': PT, 'PDT': PT}

dt_est = parse('2014-01-02 04:00:00 EST', tzinfos=us_tzinfos)
dt_pst = parse('2016-03-11 16:00:00 PST', tzinfos=us_tzinfos)

これを実行した後:

dt_est
# datetime.datetime(2014, 1, 2, 4, 0, tzinfo=tzfile('/usr/share/zoneinfo/US/Eastern'))
dt_pst
# datetime.datetime(2016, 3, 11, 16, 0, tzinfo=tzfile('/usr/share/zoneinfo/US/Pacific'))

この方法でpytzタイムゾーンを使用すると、適切にローカライズされないことに注意してください。

from dateutil.parser import parse
import pytz

EST = pytz.timezone('America/New_York')
dt = parse('2014-02-03 09:17:00 EST', tzinfos={'EST': EST})

これはpytzタイムゾーンをdatetimeに単に付加するだけです:

dt.tzinfo # Will be in Local Mean Time!
# <DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>

このメソッドを使用している場合は、解析した後、おそらく日時の素朴な部分を再localizeする必要があります。

dt_fixed = dt.tzinfo.localize(dt.replace(tzinfo=None))
dt_fixed.tzinfo # Now it's EST.
# <DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)

タイムゾーンを認識する日付時刻の作成

デフォルトでは、すべてのdatetimeオブジェクトはnaiveです。タイムゾーンを認識させるには、UTCのオフセットとタイムゾーンの省略形を日時の関数として提供するtzinfoオブジェクトを添付する必要があります。

固定オフセットタイムゾーン

Python 3.2以降では、UTCからの固定オフセットであるtimezone場合、 datetimeモジュールはtimedeltaと(オプションの)nameパラメータを取るtzinfo具体的な実装であるtimezoneクラスを提供します。

Python 3.x 3.2
from datetime import datetime, timedelta, timezone
JST = timezone(timedelta(hours=+9))

dt = datetime(2015, 1, 1, 12, 0, 0, tzinfo=JST)
print(dt)
# 2015-01-01 12:00:00+09:00

print(dt.tzname())
# UTC+09:00

dt = datetime(2015, 1, 1, 12, 0, 0, tzinfo=timezone(timedelta(hours=9), 'JST'))
print(dt.tzname)
# 'JST'

3.2より前のバージョンのPythonでは、 dateutilなどのサードパーティのライブラリを使用する必要があります。 dateutil等価クラス、提供tzoffset (バージョン2.5.3のような)形式の引数を取り、 dateutil.tz.tzoffset(tzname, offset)offset秒単位で指定されます。

Python 3.x 3.2
Python 2.x 2.7
from datetime import datetime, timedelta
from dateutil import tz

JST = tz.tzoffset('JST', 9 * 3600) # 3600 seconds per hour
dt = datetime(2015, 1, 1, 12, 0, tzinfo=JST)
print(dt)
# 2015-01-01 12:00:00+09:00
print(dt.tzname)
# 'JST'

夏時間のあるゾーン

夏時間のゾーンの場合、Python標準ライブラリは標準クラスを提供しないため、サードパーティライブラリを使用する必要があります。 pytzdateutilは、タイムゾーンクラスを提供する一般的なライブラリです。

静的な時間帯に加えて、 dateutilは夏時間を使用するタイムゾーンクラスを提供します( tzモジュールのドキュメントを参照)。 tz.gettz()メソッドを使用してタイムゾーンオブジェクトを取得し、それをdatetimeコンストラクタに直接渡すことができます。

from datetime import datetime
from dateutil import tz
local = tz.gettz() # Local time
PT = tz.gettz('US/Pacific') # Pacific time

dt_l = datetime(2015, 1, 1, 12, tzinfo=local) # I am in EST
dt_pst = datetime(2015, 1, 1, 12, tzinfo=PT)
dt_pdt = datetime(2015, 7, 1, 12, tzinfo=PT) # DST is handled automatically
print(dt_l)
# 2015-01-01 12:00:00-05:00
print(dt_pst)
# 2015-01-01 12:00:00-08:00
print(dt_pdt)
# 2015-07-01 12:00:00-07:00

注意 :バージョン2.5.3では、 dateutilはあいまいな日付時刻を正しく処理せず、常に後の日付にデフォルト設定されます。例えば2015-11-01 1:30 EDT-4表すdateutilタイムゾーンを持つオブジェクトを作成する方法はありません。これは、夏時間の移行中であるためです。

pytzを使用する場合、すべてのエッジケースが適切に処理されますが、 pytzタイムゾーンは、コンストラクタを介してタイムゾーンに直接接続されるべきでありませ 。代わりに、 pytzタイムゾーンをタイムゾーンのlocalizeメソッドを使用して接続する必要があります。

from datetime import datetime, timedelta
import pytz

PT = pytz.timezone('US/Pacific')
dt_pst = PT.localize(datetime(2015, 1, 1, 12))
dt_pdt = PT.localize(datetime(2015, 11, 1, 0, 30))
print(dt_pst)
# 2015-01-01 12:00:00-08:00
print(dt_pdt)
# 2015-11-01 00:30:00-07:00

pytz対応するタイムゾーンで日時演算を実行する場合、絶対経過時間が必要な場合はUTCで計算を実行するか、結果に対してnormalize()を呼び出す必要があります。

dt_new = dt_pdt + timedelta(hours=3) # This should be 2:30 AM PST
print(dt_new)
# 2015-11-01 03:30:00-07:00
dt_corrected = PT.normalize(dt_new)
print(dt_corrected)
# 2015-11-01 02:30:00-08:00

ファジィ日時解析(テキストからdatetimeを抽出する)

日付の一部であると認識されない文字列の構成要素が無視される「ファジー」モードのdateutilパーサーを使用して、テキストから日付を抽出することは可能です。

from dateutil.parser import parse

dt = parse("Today is January 1, 2047 at 8:21:00AM", fuzzy=True)
print(dt)

dtdatetimeオブジェクトになり、 datetime.datetime(2047, 1, 1, 8, 21)されます。

タイムゾーンの切り替え

タイムゾーンを切り替えるには、タイムゾーンを認識する日時オブジェクトが必要です。

from datetime import datetime
from dateutil import tz

utc = tz.tzutc()
local = tz.tzlocal()

utc_now = datetime.utcnow()
utc_now # Not timezone-aware.

utc_now = utc_now.replace(tzinfo=utc)
utc_now # Timezone-aware.

local_now = utc_now.astimezone(local)
local_now # Converted to local time.

最小限のライブラリで任意のISO 8601タイムスタンプを解析する

Pythonは、ISO 8601のタイムスタンプの解析を制限しています。 strptime場合、どの形式であるかを正確に知る必要があります。複雑な問題として、 datetimeの文字列化はISO 8601のタイムスタンプで、スペースは区切り文字と6桁の小数部になります。

str(datetime.datetime(2016, 7, 22, 9, 25, 59, 555555))
# '2016-07-22 09:25:59.555555'

小数部が0の場合は小数部は出力されません

str(datetime.datetime(2016, 7, 22, 9, 25, 59, 0))
# '2016-07-22 09:25:59'

しかし、これらの2 つの形式は、 strptimeために異なる形式を必要とします。さらに、 strptime' does not support at all parsing minute timezones that have ain it, thus 2016年7月22日09:25:+ 0300 59をcan be parsed, but the standard format 2016年7月22日午前9時25分59秒を+03:00`はできません。

iso8601と呼ばれる単一ファイルライブラリがあり、ISO 8601のタイムスタンプとそのファイルのみを正しく解析します。

分数とタイムゾーンをサポートし、 Tセパレータはすべて単一の関数でサポートされています:

import iso8601
iso8601.parse_date('2016-07-22 09:25:59')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22 09:25:59+03:00')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<FixedOffset '+03:00' ...>)
iso8601.parse_date('2016-07-22 09:25:59Z')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22T09:25:59.000111+03:00')
# datetime.datetime(2016, 7, 22, 9, 25, 59, 111, tzinfo=<FixedOffset '+03:00' ...>)

timezoneが設定されていない場合、 iso8601.parse_dateデフォルトはUTCになります。デフォルトゾーンはdefault_zoneキーワード引数で変更できます。特に、これがデフォルトの代わりにNoneである場合、明示的なタイムゾーンを持たないタイムスタンプは、代わりにnaive datetimesとして返されます。

iso8601.parse_date('2016-07-22T09:25:59', default_timezone=None)
# datetime.datetime(2016, 7, 22, 9, 25, 59)
iso8601.parse_date('2016-07-22T09:25:59Z', default_timezone=None)
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)

タイムスタンプをdatetimeに変換する

datetimeモジュールは、POSIX timestampをITC datetimeオブジェクトに変換できます。

エポックは1970年1月1日の深夜です。

import time
from datetime import datetime
seconds_since_epoch=time.time()  #1469182681.709

utc_date=datetime.utcfromtimestamp(seconds_since_epoch) #datetime.datetime(2016, 7, 22, 10, 18, 1, 709000)

日付から正確に月を差し引く

calendarモジュールの使用

import calendar
from datetime import date

def monthdelta(date, delta):
    m, y = (date.month+delta) % 12, date.year + ((date.month)+delta-1) // 12
    if not m: m = 12
    d = min(date.day, calendar.monthrange(y, m)[1])
    return date.replace(day=d,month=m, year=y)

next_month = monthdelta(date.today(), 1) #datetime.date(2016, 10, 23)

dateutilsモジュールの使用

import datetime
import dateutil.relativedelta

d = datetime.datetime.strptime("2013-03-31", "%Y-%m-%d")
d2 = d - dateutil.relativedelta.relativedelta(months=1)  #datetime.datetime(2013, 2, 28, 0, 0)

時間差の計算

timedeltaモジュールは時間の差を計算するのに便利です:

from datetime import datetime, timedelta
now = datetime.now()
then = datetime(2016, 5, 23)     # datetime.datetime(2016, 05, 23, 0, 0, 0)

新しいdatetimeオブジェクトを作成する場合、時間の指定はオプションです。

delta = now-then

deltatimedeltatimedelta

print(delta.days)
# 60
print(delta.seconds)
# 40826

日付のn日後とn日前に取得するには、次のものを使用します。

n日後:

def get_n_days_after_date(date_format="%d %B %Y", add_days=120):

    date_n_days_after = datetime.datetime.now() + timedelta(days=add_days)
    return date_n_days_after.strftime(date_format)

日前日:

 def get_n_days_before_date(self, date_format="%d %B %Y", days_before=120):

        date_n_days_ago = datetime.datetime.now() - timedelta(days=days_before)
        return date_n_days_ago.strftime(date_format)

ISO 8601タイムスタンプを取得する

タイムゾーンなし、マイクロ秒

from datetime import datetime

datetime.now().isoformat()
# Out: '2016-07-31T23:08:20.886783'

タイムゾーンでは、マイクロ秒

from datetime import datetime
from dateutil.tz import tzlocal

datetime.now(tzlocal()).isoformat()
# Out: '2016-07-31T23:09:43.535074-07:00'

マイクロ秒なしのタイムゾーン

from datetime import datetime
from dateutil.tz import tzlocal

datetime.now(tzlocal()).replace(microsecond=0).isoformat()
# Out: '2016-07-31T23:10:30-07:00'

ISO 8601形式の詳細については、 ISO 8601を参照してください。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow