strftimeでPythonの日時をエポックに変換する


209

エポックからの秒数を知りたいUTCの時間があります。

strftimeを使用して秒数に変換しています。2012年4月1日を例にとります。

>>>datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

エポックからの2012年4月1日のUTCは1333238400ですが、これは1時間だけ異なる1333234800を返します。

したがって、strftimeは私のシステム時間を考慮して、どこかにタイムゾーンのシフトを適用しているようです。日時は純粋にナイーブだと思いましたか?

どうすればそれを回避できますか?可能であれば、標準でない限り、他のライブラリのインポートを避けます。(私は携帯性の懸念があります)。



11
数字に8進数リテラルを使用していることに気付いたのは私だけですか?
フィッシュモニター


3
新しいPython 3.3以降のバージョンdatetime.datetime.timestamp(datetime.datetime.utcnow())
MarkHu 2018

回答:


389

Pythonの日時をエポックからの秒数に変換する場合は、明示的に行うことができます。

>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0

Python 3.3以降では、timestamp()代わりに次を使用できます。

>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0

なぜ使用すべきではないのか datetime.strftime('%s')

Pythonは実際には%sをstrftimeへの引数としてサポートしていません(http://docs.python.org/library/datetime.html#strftime-and-strptime-behaviorで確認した場合、リストにありません)。 Pythonがローカルタイムゾーンを使用するシステムのstrftimeに情報を渡すためです。

>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

7
なぜstrftime( "%s")が頻繁に表示されるのかを理解しようと夢中になっていますが、ドキュメントには記載されていません。何もありがとうございました!
Jonathan Vanasco 2013

54
使用しないでください。.strftime("%s")サポートされていないため、移植性がなく、認識されたdatetimeオブジェクトに対して誤って結果が生成される可能性があります。入力がUTCである場合は(質問のように)失敗しますが、ローカルタイムゾーンはUTCではありません
jfs

2
@earthmeLonブラケットが間違っています。タイムデルタ(2つの日時を減算して作成)にはtotal_secondsがありますが、日時にはありません。
jleahy 2013

2
これは私にとってはうまくいきません: AttributeError: 'datetime.timedelta' object has no attribute 'total_seconds'
マイケル

3
@Michaelこの関数はPython 2.7で新しく追加されました。古いバージョンを使用している必要があります。2.7より前のバージョンでは、これを行うことができますtd.seconds + td.days*24*3600。これにより、マイクロ秒の部分が破棄されます。
jleahy 14

100

タイムゾーンなどに関して深刻な問題がありました。Pythonがすべてを処理する方法は、(私にとって)非常に混乱します。物事はカレンダーモジュールを使用して正常に動作しているようだ(リンク参照12 34を)。

>>> import datetime
>>> import calendar
>>> aprilFirst=datetime.datetime(2012, 04, 01, 0, 0)
>>> calendar.timegm(aprilFirst.timetuple())
1333238400

7
+1は、質問の入力に対して機能する唯一の回答であるためです。
jfs 14

これはポータブルですか?
benjaminz 2016年

1
これは問題の懸念に答えるので、これは正しい答えとしてマークされるべきです。vnice kudos
レオプリンス

2
これは「機能」しますが、「UTCで時間があります」という質問に注意してください。この方法では、常にシステムのローカルタイムゾーンが使用されます。タイムゾーンを指定する方法はありません。場合はaprilFirst、この例では「意識」のインスタンスであり、システムのタイムゾーンと異なるタイムゾーンを使用し、結果は(タイムゾーンがで失われる正確ではありませんtimetuple()コール)。awaredt.timestamp()最新のPython 3で使用できる「認識」日時の正しい答えを得るには、Python 2の方が難しいです。1つの方法は、arrowライブラリを使用することです。arrow.get(awaredt).timestampそれは正しくなります。
アダムウィリアムソン

1
良い点、@ AdamWilliamsonですが、例のコードはdatetimeオブジェクトをローカライズしていないため、「私はUTCに時間があります」とは、OPに、彼が望んでいたUTCであると想定されている認識されていないdatetimeオブジェクトがあることを意味しました取得するには(場合、このかもしれないTZ-意識することが起こった、確かに、物事を変えます)。また、この回答はほぼ8年前のものであり、(たとえば2013年にリリースされてから)多くのことが起こっていることにもepochdatetimearrow
注意してください

35
import time
from datetime import datetime
now = datetime.now()

time.mktime(now.timetuple())

1
これは書き込み方法が正しくありませんtime.time()mktime()DSTの移行中time.time()に作業を続行すると失敗する場合があります)また、ローカルタイムゾーンがUTCでない限り、質問には回答しません(質問の入力はUTCです)。入力が現地時間を表すmktime()場合でも、tzデータベースを使用せず、ローカルタイムゾーンが複数の年にわたって異なるutcオフセットを持つ可能性がある場合、たとえば2010-2015年のヨーロッパ/モスクワ- -代わりに(質問のように)UTC時間またはタイムゾーン対応の日時オブジェクトを使用します。
jfs

here're (によって返されるようなローカル時刻を変換すると、より問題.now()(によって返されたエポックのタイムスタンプに)mktime()。読んだら あなたは(質問で使用される)UTC入力は現地時間を表すナイーブDateTimeオブジェクトよりも(ずっと)がより好ましい理由を理解する
JFS

14
import time
from datetime import datetime
now = datetime.now()

# same as above except keeps microseconds
time.mktime(now.timetuple()) + now.microsecond * 1e-6

(申し訳ありませんが、既存の回答についてコメントすることはできません)


これは、time.mktimeがマイクロ秒の部分を考慮に入れていないためです。
エドゥアルド

1
正しい。時間タプル構造体(C strutに基づく)にはマイクロ秒のスペースがないため、datetimeオブジェクトから情報を取得し、最後に追加する必要があります。
Charles Plager 2014


私のマシンでは、タイムゾーンがETであっても、これは正しく動作します。
Charles Plager 2016

1
これにより、システムのローカル時間に基づいて、システムごとに異なるタイムスタンプが提供されます。
Yousaf

6

unix / epoch時間のタイムスタンプだけが必要な場合は、次の1行が機能します。

created_timestamp = int((datetime.datetime.now() - datetime.datetime(1970,1,1)).total_seconds())
>>> created_timestamp
1522942073L

datetime python2とpython3の作品にのみ依存しています


2

これはPython 2および3で機能します。

>>> import time
>>> import calendar
>>> calendar.timegm(time.gmtime())
1504917998

ちょうど公式のドキュメントに従ってください ... https://docs.python.org/2/library/time.html#module-time


1)これは、ランダムな日時オブジェクトではなく、今すぐ変換することを前提としています。2)カレンダーは必要ありません。time.mktime(randomDateTime.timetuple())+ randomDateTime.microsecond * 1e-6
Charles Plager

@CharlesPlager time.mktimeは正しくありません。OPはローカルタイムゾーンで引数を解釈しますが、OPは(calendar.timegmが行うように)UTCで解釈される時刻を要求します。
stewbasic

これが私にとって最も正確な答えです。GMTで時刻を変換する場合、エポックタイムスタンプへの変換時にその方法を維持する必要がある場合です。
Yousaf

回答の直後、calendar.timegm(datetime.strptime( "2019-05-03T05:40:09.770494 + 00:00" [:16]、 '%Y-%m-%dT%H:%M')。 timetuple())utcにタイムスタンプがあり、どのシステムで実行しても正しいタイムスタンプが得られるかどうかに関係なく、トリックはstrptime.timetumpleを使用することです
Yousaf

2

タイムゾーンに依存しない明示的なソリューションについては、pytzライブラリを使用してください。

import datetime
import pytz

pytz.utc.localize(datetime.datetime(2012,4,1,0,0), is_dst=False).timestamp()

出力(浮動):1333238400.0


stackoverflow.com/a/21145908/4355695で同様の回答が見られましたが、これは1ライナーとして、着信データがUTCであり、.timestamp()がローカル時間であると想定していた私のユースケースに最適です。
Nikhil VJ

これは1970年未満の日付で機能します。ありがとうございます。受け入れられた回答は、1970年未満の日付では機能しません。(Python 3.7.3 64ビットAnaconda3)
canbax

-1

Python 3.7の場合

date.isoformat()およびdatetime.isoformat()によって発行された形式のいずれかで、date_stringに対応する日時を返します。具体的には、この関数はYYYY-MM-DD [* HH [:MM [:SS [.fff [fff]]]] [+ HH:MM [:SS [.ffffff]]]]という形式の文字列をサポートしますここで、*は任意の1文字に一致します。

https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat


1
これはPython 3.7で導入されたことに注意してください。
keithpjolley
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.