48

タイムゾーン対応の日時オブジェクトを、ローカルタイムゾーンの同等の非タイムゾーン対応の日時にどのように変換しますか?

私の特定のアプリケーションはDjangoを使用しています(ただし、これは実際には一般的なPythonの質問です)。

import iso8601

...。

date_str="2010-10-30T17:21:12Z"

...。

d = iso8601.parse_date(date_str)

foo = app.models.FooModel(the_date=d)
foo.save()

これにより、Djangoはエラーをスローします:

raise ValueError("MySQL backend does not support timezone-aware datetimes.")

私が必要なのは:

d = iso8601.parse_date(date_str)
local_d = SOME_FUNCTION(d)
foo = app.models.FooModel(the_date=local_d)

SOME_FUNCTIONは何でしょうか?

4

4 に答える 4

80

一般に、任意のタイムゾーン対応の日時を単純な (ローカル) 日時に変換するには、pytzモジュールを使用astimezoneして現地時間に変換しreplace、日時を単純にします。

In [76]: import pytz

In [77]: est=pytz.timezone('US/Eastern')

In [78]: d.astimezone(est)
Out[78]: datetime.datetime(2010, 10, 30, 13, 21, 12, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)

In [79]: d.astimezone(est).replace(tzinfo=None)
Out[79]: datetime.datetime(2010, 10, 30, 13, 21, 12)

ただし、特定の日時が UTC タイムゾーンにあるように見えるため、代わりにこれを行うことができます。

In [65]: d
Out[65]: datetime.datetime(2010, 10, 30, 17, 21, 12, tzinfo=tzutc())

In [66]: import datetime

In [67]: import calendar

In [68]: datetime.datetime.fromtimestamp(calendar.timegm(d.timetuple()))
Out[68]: datetime.datetime(2010, 10, 30, 13, 21, 12)

ところで、単純なローカル日時ではなく、単純な UTC 日時として日時を保存する方がよい場合があります。そうすれば、データは現地時間に依存せず、必要な場合にのみ現地時間またはその他のタイムゾーンに変換されます。可能な限りユニコードで作業し、必要な場合にのみエンコードすることに似ています。

したがって、単純な UTC で日時を保存することが最善の方法であることに同意する場合は、次のように定義するだけです。

local_d = d.replace(tzinfo=None)
于 2011-03-27T21:50:31.383 に答える
72

Djangoの最近のバージョン(少なくとも1.4.1):

from django.utils.timezone import localtime

result = localtime(some_time_object)
于 2012-08-17T16:09:04.703 に答える
3

ポータブルで堅牢なソリューションでは、tz データベースを使用する必要があります。ローカル タイムゾーンをオブジェクトとして取得するには、 moduleを使用します。pytz tzinfotzlocal

#!/usr/bin/env python
import iso8601
import tzlocal # $ pip install tzlocal

local_timezone = tzlocal.get_localzone()
aware_dt = iso8601.parse_date("2010-10-30T17:21:12Z") # some aware datetime object
naive_local_dt = aware_dt.astimezone(local_timezone).replace(tzinfo=None)

注: 次のようなものを使用したくなるかもしれません:

#!/usr/bin/env python3
# ...
naive_local_dt = aware_dt.astimezone().replace(tzinfo=None)

ただし、ローカル タイムゾーンに可変の utc オフセットがあるが、Python が特定のプラットフォームで履歴タイムゾーン データベースを使用しない場合、失敗する可能性があります。

于 2015-08-23T07:55:38.887 に答える
0

使用python-dateutilすると、ISO-8561 形式で日付を解析できます。これにより、UTC/Zulu タイムゾーンでdateutil.parsrser.parse()認識できます。datetime

を使用.astimezone()すると、別のタイムゾーンの認識可能な日時に変換できます。

を使用.replace(tzinfo=None)すると、認識された日時が単純な日時に変換されます。

from datetime import datetime
from dateutil import parser as datetime_parser
from dateutil.tz import tzutc,gettz

aware = datetime_parser.parse('2015-05-20T19:51:35.998931Z').astimezone(gettz("CET"))
naive = aware.replace(tzinfo=None)

一般的には、すべての日付を UTC に変換してその方法で保存し、必要に応じてローカルに戻すことをお勧めします。私aware.astimezone(tzutc()).replace(tzinfo=None)はUTCであることを確認し、ナイーブに変換するために使用します。

于 2015-09-29T10:04:34.880 に答える