2012-04-24 4 views
10

Pythonの日付/時間帯では長すぎますが、誰かが私に手を差し伸べることができると考えていました。Pythonはtzinfoをpytzなしで素朴なdatetimeにします

基本的には、DTCの変更を考慮してUTCで変換したいと考えています。

私はPythonのチュートリアル(ない100%正確な私は知っているが、それはする必要はありません)のいずれかから、次のクラスtzinfoを作成しました:私は、任意のdateを持って反対側に

from datetime import tzinfo, timedelta, datetime 

ZERO = timedelta(0) 
HOUR = timedelta(hours=1) 

def first_sunday_on_or_after(dt): 
    days_to_go = 6 - dt.weekday() 
    if days_to_go: 
     dt += timedelta(days_to_go) 
    return dt 

DSTSTART_2007 = datetime(1, 3, 8, 2) 
DSTEND_2007 = datetime(1, 11, 1, 1) 
DSTSTART_1987_2006 = datetime(1, 4, 1, 2) 
DSTEND_1987_2006 = datetime(1, 10, 25, 1) 
DSTSTART_1967_1986 = datetime(1, 4, 24, 2) 
DSTEND_1967_1986 = DSTEND_1987_2006 

class USTimeZone(tzinfo): 

    def __init__(self, hours, reprname, stdname, dstname): 
     self.stdoffset = timedelta(hours=hours) 
     self.reprname = reprname 
     self.stdname = stdname 
     self.dstname = dstname 

    def __repr__(self): 
     return self.reprname 

    def tzname(self, dt): 
     if self.dst(dt): 
      return self.dstname 
     else: 
      return self.stdname 

    def utcoffset(self, dt): 
     return self.stdoffset + self.dst(dt) 

    def dst(self, dt): 
     if dt is None or dt.tzinfo is None: 
      # An exception may be sensible here, in one or both cases. 
      # It depends on how you want to treat them. The default 
      # fromutc() implementation (called by the default astimezone() 
      # implementation) passes a datetime with dt.tzinfo is self. 
      return ZERO 
     assert dt.tzinfo is self 

     # Find start and end times for US DST. For years before 1967, return 
     # ZERO for no DST. 
     if 2006 < dt.year: 
      dststart, dstend = DSTSTART_2007, DSTEND_2007 
     elif 1986 < dt.year < 2007: 
      dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006 
     elif 1966 < dt.year < 1987: 
      dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986 
     else: 
      return ZERO 

     start = first_sunday_on_or_after(dststart.replace(year=dt.year)) 
     end = first_sunday_on_or_after(dstend.replace(year=dt.year)) 

     # Can't compare naive to aware objects, so strip the timezone from 
     # dt first. 
     if start <= dt.replace(tzinfo=None) < end: 
      return HOUR 
     else: 
      return ZERO 

DSTを考慮に入れて、それらが異なる時間数を知りたいと思っています。

私はこのような何か試してみた:使用するので不可能、私はpytzモジュールからlocalizeを使用するように指示し、いくつかの記事を見てきましたが、残念ながら、私は追加のモジュールを使用することはできませんよ

>>> Eastern = ustimezone.USTimeZone(-5, "Eastern", "EST", "EDT") 
>>> x = datetime.date.today() # I actually get an arbitrary date but this is for the example 
>>> x_dt = datetime.datetime.combine(x, datetime.time()) 
>>> x_dt_tz = x_dt.astimezone(Eastern) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: astimezone() cannot be applied to a naive datetime 

pyzt

私は、この素朴な日時をタイムゾーンオブジェクトにどのように得ることができるか知っていますpytzを使わずに

+1

x_dt.replace(tzinfoが=東)多分?読み込み:http://groups.google.com/group/google-appengine/browse_thread/thread/17add9b3070aad7e/b995fe7e1f16cd4e –

+1

@skyl perfect、x_dt.replace(tzinfo = Eastern).utcoffset()はdatetime.timedelta(-1)を返します。 、72000)に相当します。そのような単純なことのためにそんなに巻き込まれているようですが、助けてくれてありがとう、あなたはそれを答えとして掲示し、私はそれを受け入れます。 –

+0

DSTを 'pytz 'なしで扱うことは、Unicodeのない複数の言語を扱うようなものです。それはできますが、結果はケースの数が間違っています。 – jfs

答えて

7

x_dt.replace(tzinfo=Eastern)found from this Google Groups thread)を使用してください。

x_dt.replace(tzinfo=Eastern).utcoffset()返すdatetime.timedelta(-1, 72000)これは-4時間に相当します! (質問のコメントから)

11

@skylが提供する答えは、pytzの回答と多かれ少なかれ同等です。

ここには、該当するpytzソースがあります。それはちょうどtzinfo kwargとdatetimeオブジェクトにreplaceを呼び出します。

def localize(self, dt, is_dst=False): 
    '''Convert naive time to local time''' 
    if dt.tzinfo is not None: 
     raise ValueError('Not naive datetime (tzinfo is already set)') 
    return dt.replace(tzinfo=self) 
+2

ソースを見つけるために+1 –

+0

@CharlesMenguy:いいえ、DSTのタイムゾーンでは 'pytz'とは異なります(*" UTCで変換を行い、DSTの変更を考慮したいです。 '.replace()'は、UTCなどの固定オフセットタイムゾーンでのみ使用できます(開始から終了までの同じUTCオフセット)。 – jfs

関連する問題