9

伸びる

わかりました、今日は良い一日を過ごしていません。

正しい tzinfo オブジェクトを datetime インスタンスにアタッチし、それを strftime() すると、UTC で出力され、アタッチした美しい tzinfo オブジェクトを無視しているように見えます。

    # パイソン 2.5.4
    今 = datetime.now()
    print now.strftime( "%a %b %d %X" ) # %Xは「ロケールの適切な時刻表現」です

    pst = now.replace( tzinfo=太平洋 )
    print pst.strftime( "%a %b %d %X" )

我々が得る:

1 月 18 日月曜日 17:30:16
1 月 18 日月曜日 17:30:16

%z を追加すると、計算されたはずの差を追加できることがわかりました。

1 月 18 日(月)17:32:38
月 1 月 18 日 17:32:38 -0800

あたかも「あなたは自分でやります、フー」と言うように、そこに -8 を追加するだけです。

しかし、strftime() で単純に WITH PRECOMPUTED LOCAL TIME の文字列を取得したいのです。

strftime() を実行したときに、strftime() に時間減算計算を実行させるにはどうすればよいですか?

私が使用している完全なコードは以下のとおりです。

from datetime import tzinfo, timedelta, datetime

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

# A UTC class.

class UTC(tzinfo):
  """UTC"""
  def utcoffset(self, dt):
    return ZERO
  def tzname(self, dt):
    return "UTC"
  def dst(self, dt):
    return ZERO

utc = UTC()

# A class building tzinfo objects for fixed-offset time zones.
# Note that FixedOffset(0, "UTC") is a different way to build a
# UTC tzinfo object.
class FixedOffset(tzinfo):
  """Fixed offset in minutes east from UTC."""

  def __init__(self, offset, name):
    self.__offset = timedelta(minutes = offset)
    self.__name = name

  def utcoffset(self, dt):
    return self.__offset

  def tzname(self, dt):
    return self.__name

  def dst(self, dt):
    return ZERO

# A class capturing the platform's idea of local time.

import time as _time

STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
  DSTOFFSET = timedelta(seconds = -_time.altzone)
else:
  DSTOFFSET = STDOFFSET

DSTDIFF = DSTOFFSET - STDOFFSET

class LocalTimezone(tzinfo):
  def utcoffset(self, dt):
    if self._isdst(dt):
      return DSTOFFSET
    else:
      return STDOFFSET

  def dst(self, dt):
    if self._isdst(dt):
      return DSTDIFF
    else:
      return ZERO

  def tzname(self, dt):
    return _time.tzname[self._isdst(dt)]

  def _isdst(self, dt):
    tt = (dt.year, dt.month, dt.day,
          dt.hour, dt.minute, dt.second,
          dt.weekday(), 0, -1)
    stamp = _time.mktime(tt)
    tt = _time.localtime(stamp)
    return tt.tm_isdst > 0

Local = LocalTimezone()


# A complete implementation of current DST rules for major US time zones.

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

# In the US, DST starts at 2am (standard time) on the first Sunday in April.
DSTSTART = datetime(1, 4, 1, 2)
# and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct.
# which is the first Sunday on or after Oct 25.
DSTEND = datetime(1, 10, 25, 1)

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 first Sunday in April & the last in October.
    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

Eastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
#Central  = USTimeZone(-6, "Central",  "CST", "CDT")
#Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
Pacific = USTimeZone(-8, "Pacific",  "PST", "PDT")

now = datetime.now()
print now.strftime( "%a %b %d %X %z" )

pst = now.replace( tzinfo=Pacific )
print pst.strftime( "%a %b %d %X %z" )
4

3 に答える 3

15

.replaceは計算を行いません。新しく返されたオブジェクトの 1 つまたは複数のフィールドを単に置き換え、それが呼び出されたオブジェクトから他のすべてのフィールドをコピーします。

私があなたの状況を正しく理解していれば、(他の方法で) UTC であることがわかっているが、それ自体が ( の tzinfo 属性を持っている) ことを知らNoneない datetime オブジェクトから始めます。入っています)。

したがって、最初に、入力タイムゾーン ナイーブ オブジェクトからタイムゾーン対応オブジェクトを作成して、それがタイムゾーン UTC であることを通知します (他のすべてのフィールドは単にコピーされます)。

aware = naive.replace(tzinfo=utc)

次に、タイムゾーンに関する計算と結果の印刷を要求できます。

print aware.astimezone(Pacific).strftime('%a %b %d %X %z')
于 2010-01-19T00:04:56.263 に答える
5

時間の値を実際に変換していないのでdt.replace(tzinfo=tz)、「ちょっと待ってください。今回は実際には UTC ではなく PDT でした」と言っているだけです。datetime.astimezone(tz)おそらく代わりに使用したいと思うでしょう。

于 2010-01-18T22:50:05.030 に答える
2

Wimは正しい考えを持っていたと思います。UTCでの時刻を知りたい場合は、次を使用してください。

print pst.astimezone(UTC).strftime( "%a %b %d %X" )

UTCタイムゾーンクラスの定義を掘り下げる必要があります。Pythonがすべての可能なtzinfoのデフォルトの実装を提供したくない理由は理解していますが、UTCは基本パッケージに含まれている必要があります。

于 2010-01-18T23:05:34.793 に答える