私はPythonで日付を扱っています、そして私はJavaScriptの中で使われるためにそれらをUTCタイムスタンプに変換する必要があります。次のコードは機能しません。
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(time.mktime(d.timetuple()))
datetime.datetime(2010, 12, 31, 23, 0)
最初に日付オブジェクトをdatetimeに変換しても役に立ちません。私はこの link から例を試しましたが、
from pytz import utc, timezone
from datetime import datetime
from time import mktime
input_date = datetime(year=2011, month=1, day=15)
そして今のどちらか:
mktime(utc.localize(input_date).utctimetuple())
または
mktime(timezone('US/Eastern').localize(input_date).utctimetuple())
動作します。
それでは、一般的な質問:UTCに従って、エポック以降の日付を秒に変換する方法を教えてください。
d = date(2011, 1, 1)
がUTCの場合:
>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)
d
がローカルタイムゾーンにある場合:
>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)
ローカルタイムゾーンの深夜がUTCの深夜と同じ時間インスタンスでない場合、timestamp1
とtimestamp2
は異なる場合があります。
mktime()
は、d
が あいまいなローカル時間(たとえば、DST移行中) に対応する場合、またはutcオフセットが異なる可能性があるときにd
が過去(未来)の日付である場合、誤った結果を返すことがありますandC mktime()
は、特定のプラットフォームで tzデータベース にアクセスできません。 pytz
モジュールを使用して(たとえば、tzlocal.get_localzone()
経由で)すべてのプラットフォームでtzデータベースにアクセスできます 。また、 utcfromtimestamp()
は失敗する可能性があり、"right"
タイムゾーンが使用されている場合、mktime()
は非POSIXタイムスタンプを返す可能性があります 。
calendar.timegm()
なしでUTCの日付を表すdatetime.date
オブジェクトを変換するには:
DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY
すでにUTCの時刻を表すdatetime.datetime
(datetime.date
ではない)オブジェクトを、対応するPOSIXタイムスタンプ(float
)に変換します。
from datetime import timezone
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
注:timezone.utc
を明示的に指定する必要があります。指定しない場合、.timestamp()
は、単純なdatetimeオブジェクトがローカルタイムゾーンにあると想定します。
datetime.utcfromtimestamp()
のドキュメントから:
日時インスタンスからタイムスタンプを取得する方法はありませんが、日時インスタンスdtに対応するPOSIXタイムスタンプは、次のように簡単に計算できます。単純なdtの場合:
timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
そして、意識しているdtの場合:
timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)
興味深い読み物: エポック時間と時刻の違いは何時ですか?と何秒経過しましたか?
上記のコードをPython 2に適応させるには:
timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
timedelta.total_seconds()
は、真の除算を有効にして計算された(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
と同等です。
from __future__ import division
from datetime import datetime, timedelta
def totimestamp(dt, Epoch=datetime(1970,1,1)):
td = dt - Epoch
# return td.total_seconds()
return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6
now = datetime.utcnow()
print now
print totimestamp(now)
浮動小数点の問題 に注意してください。
2012-01-08 15:34:10.022403
1326036850.02
datetime
オブジェクトをPOSIXタイムスタンプに変換する方法assert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+
Python 3の場合:
from datetime import datetime, timedelta, timezone
Epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - Epoch) / timedelta(seconds=1)
integer_timestamp = (dt - Epoch) // timedelta(seconds=1)
Python 2:
# utc time = local time - utc offset
utc_naive = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()
unixシステムのみの場合:
>>> import datetime
>>> d = datetime.date(2011,01,01)
>>> d.strftime("%s") # <-- THIS IS THE CODE YOU WANT
'1293832800'
注1: dizzyfは、このローカライズされたタイムゾーンを適用を観察しました。製造には使用しないでください。
注2: JakubNarębskiは、オフセットを考慮したdatetimeでもこのタイムゾーン情報を無視するに注意しました(Python 2.7でテスト済み)。
仮定1: あなたは日付をタイムスタンプに変換しようとしています、しかし日付は24時間をカバーするので、その日付を表す単一のタイムスタンプはありません。私はあなたが真夜中(00:00:00.000)にその日付のタイムスタンプを表現したいと思います。
仮定2: /現在の日付が特定のタイムゾーンに関連付けられていませんが、特定のタイムゾーン(UTC)からのオフセットを決定します。日付が含まれているタイムゾーンを知らないで、特定のタイムゾーンのタイムスタンプを計算することができません。日付をローカルシステムのタイムゾーンにあるかのように扱いたいと思います。
まず、timetuple()
メンバーを使用して、日付インスタンスをさまざまな時間コンポーネントを表すTupleに変換できます。
dtt = d.timetuple() # time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)
time.mktime
を使ってそれをタイムスタンプに変換することができます。
ts = time.mktime(dtt) # 1293868800.0
この方法は、エポック時刻自体(1970-01-01)でテストすることによって検証できます。その場合、関数はその日付の現地時間帯のタイムゾーンオフセットを返す必要があります。
d = datetime.date(1970,1,1)
dtt = d.timetuple() # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
ts = time.mktime(dtt) # 28800.0
28800.0
は8時間で、これは太平洋時間帯(私がいる場所)には正しいでしょう。
python2.7ドキュメントに従うと、time.mktime()の代わりにcalendar.timegm()を使わなければなりません。
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(calendar.timegm(d.timetuple()))
datetime.datetime(2011, 1, 1, 0, 0)
私は自分自身の2つの関数を定義しました
ここに:
import time
import datetime
from pytz import timezone
import calendar
import pytz
def utc_time2datetime(utc_time, tz=None):
# convert utc time to utc datetime
utc_datetime = datetime.datetime.fromtimestamp(utc_time)
# add time zone to utc datetime
if tz is None:
tz_datetime = utc_datetime.astimezone(timezone('utc'))
else:
tz_datetime = utc_datetime.astimezone(tz)
return tz_datetime
def datetime2utc_time(datetime):
# add utc time zone if no time zone is set
if datetime.tzinfo is None:
datetime = datetime.replace(tzinfo=timezone('utc'))
# convert to utc time zone from whatever time zone the datetime is set to
utc_datetime = datetime.astimezone(timezone('utc')).replace(tzinfo=None)
# create a time Tuple from datetime
utc_timetuple = utc_datetime.timetuple()
# create a time element from the Tuple an add microseconds
utc_time = calendar.timegm(utc_timetuple) + datetime.microsecond / 1E6
return utc_time
arrow packageを使用します。
>>> import arrow
>>> arrow.get(2010, 12, 31).timestamp
1293753600
>>> time.gmtime(1293753600)
time.struct_time(tm_year=2010, tm_mon=12, tm_mday=31,
tm_hour=0, tm_min=0, tm_sec=0,
tm_wday=4, tm_yday=365, tm_isdst=0)
質問は少し混乱しています。タイムスタンプはUTCではありません - それらはUnixのものです。日付はUTCかもしれません?そうだと仮定して、そしてあなたがPython 3.2+を使っているなら、 simple-date はこれを簡単にする:
>>> SimpleDate(date(2011,1,1), tz='utc').timestamp
1293840000.0
実際に年、月、日がある場合はdate
を作成する必要はありません。
>>> SimpleDate(2011,1,1, tz='utc').timestamp
1293840000.0
日付が他のタイムゾーンにある場合(これは、関連する時間なしで 午前0時 を想定しているため重要です)。
>>> SimpleDate(date(2011,1,1), tz='America/New_York').timestamp
1293858000.0
[simple-dateの背後にある考え方は、すべてのpythonの日付と時刻のものを1つの一貫したクラスに集めることです。そのため、どんな変換も行うことができます。それで、例えば、それはまた他の方法で行くでしょう:
>>> SimpleDate(1293858000, tz='utc').date
datetime.date(2011, 1, 1)
]
完全な時間文字列は次のものを含みます。
[+HHMM or -HHMM]
例えば:
1970-01-01 06:00:00 +0500
== 1970-01-01 01:00:00 +0000
== UNIX timestamp:3600
$ python3
>>> from datetime import datetime
>>> from calendar import timegm
>>> tm = '1970-01-01 06:00:00 +0500'
>>> fmt = '%Y-%m-%d %H:%M:%S %z'
>>> timegm(datetime.strptime(tm, fmt).utctimetuple())
3600
注意:
UNIX timestamp
は、エポック以降の秒数で表現された浮動小数点数で、 _ utc _ で表されます。
編集:
$ python3
>>> from datetime import datetime, timezone, timedelta
>>> from calendar import timegm
>>> dt = datetime(1970, 1, 1, 6, 0)
>>> tz = timezone(timedelta(hours=5))
>>> timegm(dt.replace(tzinfo=tz).utctimetuple())
3600