title: Python pass tzinfo to naive datetime without pytz
body: <p>I've been struggling for way too long on dates/timezones in Python and was thinking someone could give me a hand here.</p>
  
  <p>Basically I want to do a conversion in UTC and taking into account DST changes.</p>
  
  <p>I've created the following tzinfo class from one of the Python tutorials (not 100% accurate I know but it doesn't need to):</p>
  
  <pre><code>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 &lt; dt.year:
              dststart, dstend = DSTSTART_2007, DSTEND_2007
          elif 1986 &lt; dt.year &lt; 2007:
              dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
          elif 1966 &lt; dt.year &lt; 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 &lt;= dt.replace(tzinfo=None) &lt; end:
              return HOUR
          else:
              return ZERO
  </code></pre>
  
  <p>On the other side I have an arbitrary <code>date</code> object in EST, and I want to know the number of hours they differ by taking into account DST.</p>
  
  <p>I've tried something like this:</p>
  
  <pre><code>&gt;&gt;&gt; Eastern = ustimezone.USTimeZone(-5, "Eastern",  "EST", "EDT")
  &gt;&gt;&gt; x = datetime.date.today() # I actually get an arbitrary date but this is for the example
  &gt;&gt;&gt; x_dt = datetime.datetime.combine(x, datetime.time())
  &gt;&gt;&gt; x_dt_tz = x_dt.astimezone(Eastern)
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  ValueError: astimezone() cannot be applied to a naive datetime
  </code></pre>
  
  <p>I've seen several posts who tell to use <code>localize</code> from the <code>pytz</code> module, but unfortunately I am not able to use additional modules, so impossible to use <code>pyzt</code></p>
  
  <p>Does anyone know how I can get this naive datetime into a timezoned object <strong>without using pytz</strong>?</p>