266

UTCとの間で時間を変換する必要はありませんでした。最近、アプリにタイムゾーンを認識させるように要求されました。私は自分自身を輪になって走らせています。現地時間をUTCに変換するための情報はたくさんありますが、これはかなり初歩的なものでした(おそらく私も間違っていると思います)が、UTC時間をエンドユーザーのタイムゾーンに簡単に変換するための情報は見つかりません。

一言で言えば、Androidアプリは私(appengineアプリ)のデータを送信し、そのデータ内にタイムスタンプがあります。そのタイムスタンプを私が使用しているUTC時間に保存するには:

datetime.utcfromtimestamp(timestamp)

それは機能しているようです。私のアプリがデータを保存するとき、それは5時間先に保存されています(私はEST -5です)

データはappengineのBigTableに保存されており、取得すると次のような文字列として出力されます。

"2011-01-21 02:37:21"

この文字列をユーザーの正しいタイムゾーンでDateTimeに変換するにはどうすればよいですか?

また、ユーザーのタイムゾーン情報に推奨されるストレージは何ですか?(通常、tz情報をどのように保存しますか?「-5:00」や「EST」など)最初の質問への回答には、2番目の質問への回答というパラメーターが含まれている可能性があります。

4

16 に答える 16

506

tzinfo独自のオブジェクトを提供したくない場合は、 python-dateutilライブラリを確認してください。これは、 zoneinfo(Olson)データベースtzinfo上に実装を提供し、タイムゾーンルールをやや標準的な名前で参照できるようにします。

from datetime import datetime
from dateutil import tz

# METHOD 1: Hardcode zones:
from_zone = tz.gettz('UTC')
to_zone = tz.gettz('America/New_York')

# METHOD 2: Auto-detect zones:
from_zone = tz.tzutc()
to_zone = tz.tzlocal()

# utc = datetime.utcnow()
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in UTC time zone since 
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)

# Convert time zone
central = utc.astimezone(to_zone)

拡張された例を編集strptimeして使用法を表示する

編集2APIの使用法を修正して、より適切なエントリポイントメソッドを表示する

編集3タイムゾーンに含まれる自動検出メソッド(ヤリン)

于 2011-01-23T01:23:37.850 に答える
61

これは、外部ライブラリに依存しない回復力のある方法です。

from datetime import datetime
import time

def datetime_from_utc_to_local(utc_datetime):
    now_timestamp = time.time()
    offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
    return utc_datetime + offset

これにより、DelboyJayの例のタイミングの問題が回避されます。そして、ErikvanOostenの修正案におけるタイミングの問題は少ない。

興味深い脚注として、上記で計算されたタイムゾーンオフセットは、おそらく夏時間規則の変更により、次の一見同等の式とは異なる場合があります。

offset = datetime.fromtimestamp(0) - datetime.utcfromtimestamp(0) # NO!

更新:このスニペットには、現在の時刻のUTCオフセットを使用するという弱点があります。これは、入力日時のUTCオフセットとは異なる場合があります。別の解決策については、この回答に関するコメントを参照してください。

さまざまな時間を回避するには、経過した時間からエポック時間を取得します。これが私が行うことです。

def utc2local(utc):
    epoch = time.mktime(utc.timetuple())
    offset = datetime.fromtimestamp(epoch) - datetime.utcfromtimestamp(epoch)
    return utc + offset
于 2013-10-08T03:24:25.520 に答える
32

tzinfoオブジェクトに関する日時のドキュメントを参照してください。自分でサポートしたいタイムゾーンを実装する必要があります。これらは、ドキュメントの下部にある例です。

簡単な例を次に示します。

from datetime import datetime,tzinfo,timedelta

class Zone(tzinfo):
    def __init__(self,offset,isdst,name):
        self.offset = offset
        self.isdst = isdst
        self.name = name
    def utcoffset(self, dt):
        return timedelta(hours=self.offset) + self.dst(dt)
    def dst(self, dt):
            return timedelta(hours=1) if self.isdst else timedelta(0)
    def tzname(self,dt):
         return self.name

GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')

print datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z')

t = datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print t
print t.astimezone(EST)

出力

01/22/2011 21:52:09 
01/22/2011 21:52:09 GMT
01/22/2011 16:52:09 EST
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00a
于 2011-01-22T21:22:15.987 に答える
26

あいまいな現地時間に対応する時間(たとえば、DST移行中)でも正しい結果を取得したい場合、および/またはローカルUTCオフセットがローカルタイムゾーンの異なる時間で異なる場合は、タイムゾーンを使用しますpytz

#!/usr/bin/env python
from datetime import datetime
import pytz    # $ pip install pytz
import tzlocal # $ pip install tzlocal

local_timezone = tzlocal.get_localzone() # get pytz tzinfo
utc_time = datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_timezone)
于 2015-10-02T09:57:55.637 に答える
18

この回答は、以外のモジュールを使用したくない場合に役立ちますdatetime

datetime.utcfromtimestamp(timestamp)ナイーブdatetimeオブジェクト(認識されていないオブジェクト)を返します。認識しているものはタイムゾーンを認識していますが、ナイーブはそうではありません。タイムゾーン間(UTCと現地時間など)で変換する場合は、認識している必要があります。

開始日をインスタンス化するのはあなたではないがdatetime、UTC時間でナイーブなオブジェクトを作成できる場合は、次のPython3.xコードを試して変換することをお勧めします。

import datetime

d=datetime.datetime.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S") #Get your naive datetime object
d=d.replace(tzinfo=datetime.timezone.utc) #Convert it to an aware datetime object in UTC time.
d=d.astimezone() #Convert it to your local timezone (still aware)
print(d.strftime("%d %b %Y (%I:%M:%S:%f %p) %Z")) #Print it with a directive of choice

タイムゾーンが現在MDTである場合、MSTを出力するため、上記のコードでは夏時間が機能しないと誤解しないように注意してください。月を8月に変更すると、MDTが出力されることに注意してください。

datetime(Python 3.xでも)認識オブジェクトを取得するもう1つの簡単な方法は、最初に指定されたタイムゾーンでオブジェクトを作成することです。UTCを使用した例を次に示します。

import datetime, sys

aware_utc_dt_obj=datetime.datetime.now(datetime.timezone.utc) #create an aware datetime object
dt_obj_local=aware_utc_dt_obj.astimezone() #convert it to local time

#The following section is just code for a directive I made that I liked.
if sys.platform=="win32":
    directive="%#d %b %Y (%#I:%M:%S:%f %p) %Z"
else:
    directive="%-d %b %Y (%-I:%M:%S:%f %p) %Z"

print(dt_obj_local.strftime(directive))

Python 2.xを使用している場合は、Python 2.xには存在しないため、サブクラス化して、認識可能なオブジェクトdatetime.tzinfoを作成するためにそれを使用する必要があります。datetimedatetime.timezone

于 2017-09-21T08:53:40.807 に答える
10

Djangoを使用している場合は、次のtimezone.localtime方法を使用できます。

from django.utils import timezone
date 
# datetime.datetime(2014, 8, 1, 20, 15, 0, 513000, tzinfo=<UTC>)

timezone.localtime(date)
# datetime.datetime(2014, 8, 1, 16, 15, 0, 513000, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
于 2014-08-04T14:08:23.553 に答える
4

以下は、米国西部のクラウド環境で私のために働いた:

import datetime
import pytz

#set the timezone
tzInfo = pytz.timezone('America/Los_Angeles')
dt = datetime.datetime.now(tz=tzInfo)
print(dt)
于 2021-05-11T17:08:00.330 に答える
3

矢印を使用できます

from datetime import datetime
import arrow

now = datetime.utcnow()

print(arrow.get(now).to('local').format())
# '2018-04-04 15:59:24+02:00'

何でも食べarrow.get()られます。タイムスタンプ、ISO文字列など

于 2018-04-04T14:07:13.327 に答える
3

率直な回答を便利な方法に統合します。

import calendar
import datetime

def to_local_datetime(utc_dt):
    """
    convert from utc datetime to a locally aware datetime according to the host timezone

    :param utc_dt: utc datetime
    :return: local timezone datetime
    """
    return datetime.datetime.fromtimestamp(calendar.timegm(utc_dt.timetuple()))
于 2020-02-21T05:51:15.473 に答える
2

calendar.timegmUnixエポック以降の時間を秒time.localtimeに変換し、元に戻すために使用できます。

import calendar
import time

time_tuple = time.strptime("2011-01-21 02:37:21", "%Y-%m-%d %H:%M:%S")
t = calendar.timegm(time_tuple)

print time.ctime(t)

与えるFri Jan 21 05:37:21 2011(私はUTC + 03:00タイムゾーンにいるため)。

于 2017-06-08T15:52:15.620 に答える
2
import datetime

def utc_str_to_local_str(utc_str: str, utc_format: str, local_format: str):
    """
    :param utc_str: UTC time string
    :param utc_format: format of UTC time string
    :param local_format: format of local time string
    :return: local time string
    """
    temp1 = datetime.datetime.strptime(utc_str, utc_format)
    temp2 = temp1.replace(tzinfo=datetime.timezone.utc)
    local_time = temp2.astimezone()
    return local_time.strftime(local_format)

utc_tz_example_str = '2018-10-17T00:00:00.111Z'
utc_fmt = '%Y-%m-%dT%H:%M:%S.%fZ'
local_fmt = '%Y-%m-%dT%H:%M:%S+08:00'

# call my function here
local_tz_str = utc_str_to_local_str(utc_tz_example_str, utc_fmt, local_fmt)
print(local_tz_str)   # 2018-10-17T08:00:00+08:00

utc_tz_example_str= 2018-10-17T00:00:00.111Z、(UTC +00:00)<br />と入力すると、次のようになりますlocal_tz_str= 2018-10-17T08:00:00 + 08:00 (目標タイムゾーン+08 :00)</ p>

パラメータutc_formatは、特定のによって決定される形式ですutc_tz_example_str
パラメータlocal_fmtは、最終的に必要な形式です。

私の場合、希望する形式は%Y-%m-%dT%H:%M:%S+08:00(+08:00タイムゾーン)です。必要な形式を作成する必要があります。

于 2018-10-17T10:50:52.093 に答える
1

私は伝統的にこれをフロントエンドに延期します-タイムスタンプまたはUTCの他の日時形式としてバックエンドから時間を送信し、クライアントにタイムゾーンオフセットを計算させ、このデータを適切なタイムゾーンでレンダリングします。

Webアプリの場合、これはjavascriptで非常に簡単に実行できます。組み込みのメソッドを使用して、ブラウザーのタイムゾーンオフセットを非常に簡単に把握し、バックエンドからのデータを適切にレンダリングできます。

于 2011-01-23T00:58:06.890 に答える
1

ここでの回答から、タイムモジュールを使用して、UTCからコンピューターに設定されている現地時間に変換できます。

utc_time = time.strptime("2018-12-13T10:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
utc_seconds = calendar.timegm(utc_time)
local_time = time.localtime(utc_seconds)
于 2018-12-13T11:52:48.300 に答える
0

これは、ローカルシステム設定を使用して時差を計算するクイックでダーティなバージョンです。注:現在のシステムが実行されていないタイムゾーンに変換する必要がある場合、これは機能しません。BSTタイムゾーンで英国の設定を使用してこれをテストしました

from datetime import datetime
def ConvertP4DateTimeToLocal(timestampValue):
   assert isinstance(timestampValue, int)

   # get the UTC time from the timestamp integer value.
   d = datetime.utcfromtimestamp( timestampValue )

   # calculate time difference from utcnow and the local system time reported by OS
   offset = datetime.now() - datetime.utcnow()

   # Add offset to UTC time and return it
   return d + offset
于 2013-04-15T09:38:26.420 に答える
0

これは私のために働いた:

from django.utils import timezone
from datetime import timedelta,datetime

ist_time = timezone.now() + timedelta(hours=5,minutes=30)

#second method

ist_time = datetime.now() + timedelta(hours=5,minutes=30)
于 2022-01-21T13:08:03.300 に答える
0

短くてシンプル:

from datetime import datetime

t = "2011-01-21 02:37:21"
datetime.fromisoformat(t) + (datetime.now() - datetime.utcnow())
于 2022-02-09T18:44:36.910 に答える