PythonでのISO時間(ISO 8601)


340

ファイルがあります。Pythonでは、その作成時間を取得し、それがISO時間(ISO 8601)文字列に 変換されるようにしながら、それが東部標準時(ET)でます。

ファイルのctimeを取り、それを東部タイムゾーンを示すISO時間文字列に変換する方法(および必要に応じて夏時間を考慮)



11
@ Nick-便利なリンクですが、複製ではありません-彼は他の方法で変換することを求めています。
Yarin

1
@ Joseph-私はRFC 3999に関してこれを尋ねました-これでうまくいくはずです-PythonでRFC 3339タイムスタンプを生成します
Yarin

回答:


560

ISO 8601に対してローカル:

import datetime
datetime.datetime.now().isoformat()
>>> 2020-03-20T14:28:23.382748

ISO 8601へのUTC:

import datetime
datetime.datetime.utcnow().isoformat()
>>> 2020-03-20T01:30:08.180856

マイクロ秒なしのISO 8601にローカル:

import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
>>> 2020-03-20T14:30:43

TimeZone情報を含むISO 8601へのUTC(Python 3):

import datetime
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat()
>>> 2020-03-20T01:31:12.467113+00:00

マイクロ秒なしのローカルTimeZone情報を含むISO 8601へのUTC(Python 3):

import datetime
datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
>>> 2020-03-20T14:31:43+13:00

TimeZone情報を含むISO 8601のローカル(Python 3):

import datetime
datetime.datetime.now().astimezone().isoformat()
>>> 2020-03-20T14:32:16.458361+13:00

astimezone()utc時間での使用にはバグがあることに注意してください。これは誤った結果をもたらします:

datetime.datetime.utcnow().astimezone().isoformat() #Incorrect result

Python 2の場合は、pytzを参照して使用してください


17
.isoformat()セパレータパラメータを取ることができます( 'T'以外のものが必要な場合):.isoformat(' ')
ThorSummoner

5
@ThorSummoner知っておきたい!ただし、セパレーターを変更してもISO-8601に準拠しなくなることに注意してください...これはあまり意味がありません(日付を印刷する方法は他にもありますが、ここでは問題ではありませんでした)。RFC
estani

4
ISO-8601規格の一部としてスペースが許可されています。It is permitted to omit the 'T' character by mutual agreement.
raychi 2016

4
@raychi相互の合意によって標準を変更することは常に許可されています(多くの場合、標準に違反しますが、それが相互の合意であるかどうかは誰が気にしますか?)。私の2c:しないで、そのままにしておきます。
estani

14
datetime.datetime.now()。isoformat()はローカルのラベルを付けずにローカルのISO 8601文字列を返すため、この回答は誤りです。isoformatが正しいことを行うには、ローカルのタイムゾーンを表すdatetime.timezoneが必要です。
Sam Hartman 2017

66

XSD日時形式に変換するために使用するものを次に示します。

from datetime import datetime
datetime.now().replace(microsecond=0).isoformat()
# You get your ISO string

XSD日付時刻形式(xs:dateTime)を探しているときに、この質問に出くわしました。からマイクロ秒を削除する必要がありましたisoformat


4
「XSD」とは(このコンテキストでは)?
Peter Mortensen

1
私は彼xs:dateがXSD / XMLスタイルシートから意味していると思います。
sventechie

1
それは意味しますxs:dateTime
radtek '19年

56

ISO 8601時間表現

国際標準ISO 8601は、日付と時刻の文字列表現を記述しています。この形式の2つの簡単な例は次のとおりです。

2010-12-16 17:22:15
20101216T172215

(どちらも2010年12月16日を表します)が、この形式では1秒未満の解決時間とタイムゾーンの指定も可能です。この形式はもちろんPython固有ではありませんが、日付と時刻を移植可能な形式で格納するのに適しています。このフォーマットの詳細については、Markus Kuhnのエントリをご覧ください。ます。

時間をファイルに保存するには、この形式を使用することをお勧めします。

この表現で現在の時刻を取得する1つの方法は、Python標準ライブラリのtimeモジュールからstrftimeを使用することです。

>>> from time import strftime
>>> strftime("%Y-%m-%d %H:%M:%S")
'2010-03-03 21:16:45'

datetimeクラスのstrptimeコンストラクターを使用できます。

>>> from datetime import datetime
>>> datetime.strptime("2010-06-04 21:08:12", "%Y-%m-%d %H:%M:%S")
datetime.datetime(2010, 6, 4, 21, 8, 12)

最も堅牢なのはEgenix mxDateTimeモジュールです。

>>> from mx.DateTime.ISO import ParseDateTimeUTC
>>> from datetime import datetime
>>> x = ParseDateTimeUTC("2010-06-04 21:08:12")
>>> datetime.fromtimestamp(x)
datetime.datetime(2010, 3, 6, 21, 8, 12)

参考文献


2
どのような意味で「より堅牢」ですか?
ステファン・

日付:2018-05-25
loxaxs

UTCでの日付と時刻の組み合わせ:2018-05-25T12:16:14+00:00
loxaxs '25年

2
UTCでの日付と時刻の組み合わせ:2018-05-25T12:16:14Z
loxaxs '25年

UTCでの日付と時刻の組み合わせ:20180525T121614Z
loxaxs '25年

49

ドキュメントで datetime.isoformatを見つけました。それはあなたが望むことをするようです:

datetime.isoformat([sep])

Return a string representing the date and time in ISO 8601 format, YYYY-MM-DDTHH:MM:SS.mmmmmm or, if microsecond is 0, YYYY-MM-DDTHH:MM:SS

If utcoffset() does not return None, a 6-character string is appended, giving the UTC offset in (signed) hours and minutes: YYYY-MM-DDTHH:MM:SS.mmmmmm+HH:MM or, if microsecond is 0 YYYY-MM-DDTHH:MM:SS+HH:MM

The optional argument sep (default 'T') is a one-character separator, placed between the date and time portions of the result. For example,
>>>

>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
...     def utcoffset(self, dt): return timedelta(minutes=-399)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'

30

ISO 8601では、を除いてセパレータを使用しないコンパクトな表現が可能であるため、Tこのワンライナーを使用して迅速なタイムスタンプ文字列を取得します。

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%S.%fZ")
'20180905T140903.591680Z'

マイクロ秒が必要ない場合は、.%f部分を省略してください:

>>> datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
'20180905T140903Z'

現地時間の場合:

>>> datetime.datetime.now().strftime("%Y%m%dT%H%M%S")
'20180905T140903'

編集:

これについてもう少し読んだ後、句読点はそのままにしておくことをお勧めします。RFC3339はそのスタイルを推奨しています。なぜなら、すべての人が句読点を使用する場合、複数のISO 8601文字列が句読点でグループにソートされるなどのリスクはないからです。したがって、準拠文字列の1つのライナーは次のようになります。

>>> datetime.datetime.now().strftime("%Y-%m-%dT%H:%M%SZ")
'2018-09-05T14:09:03Z'

3
ミリ秒の桁を3に制限する方法はありますか?つまり、他のJavaScriptアプリで生成さ2019-02-23T04:02:04.051Zれるnew Date().toISOString()
ミランダ

19

ISO 8601時刻の形式オフセットのみ対応UTCが保存され、タイムゾーンの名前を格納しません。

Python 3でUTCオフセットを維持しながら、ファイルctimeをISO 8601時間文字列に変換するには:

>>> import os
>>> from datetime import datetime, timezone
>>> ts = os.path.getctime(some_file)
>>> dt = datetime.fromtimestamp(ts, timezone.utc)
>>> dt.astimezone().isoformat()
'2015-11-27T00:29:06.839600-05:00'

コードは、ローカルタイムゾーンが 東部標準時(ET)であり、システムが指定されたPOSIXタイムスタンプ(ts)の。つまり、Pythonはシステムの履歴タイムゾーンデータベースにアクセスできるか、特定の日付で同じルール。

ポータブルソリューションが必要な場合。tzデータベースへのアクセスを提供するpytzモジュール使用します

>>> import os
>>> from datetime import datetime
>>> import pytz  # pip install pytz
>>> ts = os.path.getctime(some_file)
>>> dt = datetime.fromtimestamp(ts, pytz.timezone('America/New_York'))
>>> dt.isoformat()
'2015-11-27T00:29:06.839600-05:00'

この場合の結果は同じです。

タイムゾーン名/略称/ゾーンIDが必要な場合は、別に保存してください。

>>> dt.astimezone().strftime('%Y-%m-%d %H:%M:%S%z (%Z)')
'2015-11-27 00:29:06-0500 (EST)'

注:いいえ、:UTCオフセットでは、ESTタイムゾーンの省略形はISO 8601時間形式の一部ではありません。それはユニークではありません。

同じライブラリの異なるライブラリ/異なるバージョンは、同じ日付/タイムゾーンに対して異なるタイムゾーンルールを使用する場合があります。それが将来の日付である場合、ルールはまだ不明である可能性があります。言い換えると、使用するルールによっては、同じUTC時刻が異なるローカル時刻に対応する場合があります。ISO8601形式で時刻を保存すると、プラットフォームで使用されている現在のタイムゾーンルールに対応するUTC時刻とローカル時刻が保持されます。 。ルールが異なる場合、別のプラットフォームの現地時間を再計算する必要がある場合があります。


14

あなたは使用する必要がありますos.statファイルの作成時刻との組み合わせを取得するtime.strftimeと、time.timezone書式設定のために:

>>> import time
>>> import os
>>> t = os.stat('C:/Path/To/File.txt').st_ctime
>>> t = time.localtime(t)
>>> formatted = time.strftime('%Y-%m-%d %H:%M:%S', t)
>>> tz = str.format('{0:+06.2f}', float(time.timezone) / 3600)
>>> final = formatted + tz
>>> 
>>> final
'2008-11-24 14:46:08-02.00'

タイムゾーンは夏時間を考慮していますか?夏時間に関係なくtzは同じになるようです。
ジョセフトゥリアン

2
現在有効なオフセットです。DSTがアクティブな場合、DSTがアクティブでない場合とはオフセットが異なります。
Max Shawabkeh 2010年

4

私が間違っている(私が間違っている)場合は修正してください。ただし、UTCからのオフセットは夏時間で変化します。だからあなたは使うべきです

tz = str.format('{0:+06.2f}', float(time.altzone) / 3600)

私はまた、標識が異なっているべきだと信じています:

tz = str.format('{0:+06.2f}', -float(time.altzone) / 3600)

私は間違っているかもしれませんが、私はそうは思いません。


2

Jarekに同意します。さらに、ISOオフセット区切り文字はコロンであるため、最終的な答えは次のようになるはずです。

isodate.datetime_isoformat(datetime.datetime.now()) + str.format('{0:+06.2f}', -float(time.timezone) / 3600).replace('.', ':')

2

エスタニの小さなバリエーションを追加する 素晴らしい答えに

TimeZoneを使用しマイクロ秒情報を含まない ISO 8601のローカル(Python 3):

import datetime, time

utc_offset_sec = time.altzone if time.localtime().tm_isdst else time.timezone
utc_offset = datetime.timedelta(seconds=-utc_offset_sec)
datetime.datetime.now().replace(microsecond=0, tzinfo=datetime.timezone(offset=utc_offset)).isoformat()

出力例:

'2019-11-06T12:12:06-08:00'

この出力がJavaScript DateとC#の両方で解析できることをテストしましたDateTime/DateTimeOffset


1

私はこの関数を開発しました:

def iso_8601_format(dt):
    """YYYY-MM-DDThh:mm:ssTZD (1997-07-16T19:20:30-03:00)"""

    if dt is None:
        return ""

    fmt_datetime = dt.strftime('%Y-%m-%dT%H:%M:%S')
    tz = dt.utcoffset()
    if tz is None:
        fmt_timezone = "+00:00"
    else:
        fmt_timezone = str.format('{0:+06.2f}', float(tz.total_seconds() / 3600))

    return fmt_datetime + fmt_timezone

-6
import datetime, time    
def convert_enddate_to_seconds(self, ts):
    """Takes ISO 8601 format(string) and converts into epoch time."""
     dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+\
                datetime.timedelta(hours=int(ts[-5:-3]),
                minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
    seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
    return seconds 

>>> import datetime, time
>>> ts = '2012-09-30T15:31:50.262-08:00'
>>> dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+ datetime.timedelta(hours=int(ts[-5:-3]), minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
>>> seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
>>> seconds
1348990310.26
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.