timezone.py :  » Web-Services » python-xmltv » pytvgrab-lib-0.5.1 » lib » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Services » python xmltv 
python xmltv » pytvgrab lib 0.5.1 » lib » timezone.py
#!/usr/bin/env python
# -----------------------------------------------------------------------
# Copyright (C) 2004 Dan Fritz.
# Copyright (C) Gustavo Niemeyer <niemeyer@conectiva.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
# -----------------------------------------------------------------------
#
# This code is part of the pytvgrab project:
#    http://pytvgrab.sourceforge.net
#
# It consists of two parts:
# * A VERY simple implementation of some tzinfo classes for non-posix users
# * And a tzinfo implementation reading the TZ database of a posix system
#
# The windows (non-posix) version of this library:
# -----------------------------------
# uses simple DST transition rules
# and I have not even bothered to comply with DST rules prior to year 2000
#
# This is an enhanced version of the tzinfo example implementation
# found in the Python Library Reference, rev 2.3.4
#
# The tests are generated by a Java program, using the Java Timezone
# as a reference. If there is an error in the DST data the error is in the
# Java runtime libraries.
#
# The posix version:
# -----------------
# Is a stripped down version of the class tzfile found here:
# http://moin.conectiva.com.br/DateUtil
# It uses the TZ database of the posix system, so this implementation
# is much more accurate and reliable.
#
# -----------------------------------------------------------------------
# Subversion Information, do not edit
#
# $Rev: $
# $LastChangedDate: $
# $LastChangedRevision: $
# $LastChangedBy: $
#
# $Log: $
#

import datetime
import struct
import time
import os

################################################################################
################  Generic section ##############################################
################################################################################

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

# A class building tzinfo objects for fixed-offset time zones.
class FixedOffset(datetime.tzinfo):
  """Fixed offset in minutes east from UTC."""

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

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

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

  def dst(self, dt):
    return ZERO

# This is the only public part of the module:
def timezone(tz_name):
  """
  Returns a tzinfo implementation by name
  """
  if os.name == "posix":
    tz = _posix_timezone(tz_name)
  else:
    tz = _win_timezone(tz_name)
  
  assert tz, _("Could not find the timezone: %s") % tz_name
  return tz
    
################################################################################
#                        Posix section                                         #
################################################################################  
  
ZERO = datetime.timedelta(0)
EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()

class _ttinfo(object):
  # Copyright (C) Gustavo Niemeyer <niemeyer at conectiva dot com>.
  __slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"]

  def __init__(self):
    for attr in self.__slots__:
      setattr(self, attr, None)

  def __repr__(self):
    l = []
    for attr in self.__slots__:
      value = getattr(self, attr)
      if value is not None:
        l.append("%s=%s" % (attr, `value`))
    return "%s(%s)" % (self.__class__.__name__, ", ".join(l))

  def __eq__(self, other):
    if not isinstance(other, _ttinfo):
      return False
    return (self.offset == other.offset and
        self.delta == other.delta and
        self.isdst == other.isdst and
        self.abbr == other.abbr and
        self.isstd == other.isstd and
        self.isgmt == other.isgmt)

  def __ne__(self, other):
    return not self.__eq__(other)
    
class TzFile(datetime.tzinfo):
  # Copyright (C) Gustavo Niemeyer <niemeyer at conectiva dot com>.
  # http://www.twinsun.com/tz/tz-link.htm
  # ftp://elsie.nci.nih.gov/pub/tz*.tar.gz
  
  def __init__(self, fileobj):
  
    if isinstance(fileobj, basestring):
      self._s = fileobj
      fileobj = open(fileobj)
    elif hasattr(fileobj, "name"):
      self._s = fileobj.name
    else:
      self._s = `fileobj`

    # From TzFile(5):
    #
    # The time zone information files used by tzset(3)
    # begin with the magic characters "TZif" to identify
    # them as time zone information files, followed by
    # sixteen bytes reserved for future use, followed by
    # six four-byte values of type long, written in a
    # ``standard'' byte order (the high-order  byte
    # of the value is written first).

    if fileobj.read(4) != "TZif":
      raise ValueError, "magic not found"

    fileobj.read(16)

    (
     # The number of UTC/local indicators stored in the file.
     ttisgmtcnt,

     # The number of standard/wall indicators stored in the file.
     ttisstdcnt,
     
     # The number of leap seconds for which data is
     # stored in the file.
     leapcnt,

     # The number of "transition times" for which data
     # is stored in the file.
     timecnt,

     # The number of "local time types" for which data
     # is stored in the file (must not be zero).
     typecnt,

     # The  number  of  characters  of "time zone
     # abbreviation strings" stored in the file.
     charcnt,

    ) = struct.unpack(">6l", fileobj.read(24))

    # The above header is followed by tzh_timecnt four-byte
    # values  of  type long,  sorted  in ascending order.
    # These values are written in ``standard'' byte order.
    # Each is used as a transition time (as  returned  by
    # time(2)) at which the rules for computing local time
    # change.

    if timecnt:
      self._trans_list = struct.unpack(">%dl" % timecnt,
                       fileobj.read(timecnt*4))
    else:
      self._trans_list = []

    # Next come tzh_timecnt one-byte values of type unsigned
    # char; each one tells which of the different types of
    # ``local time'' types described in the file is associated
    # with the same-indexed transition time. These values
    # serve as indices into an array of ttinfo structures that
    # appears next in the file.
    
    if timecnt:
      self._trans_idx = struct.unpack(">%dB" % timecnt,
                      fileobj.read(timecnt))
    else:
      self._trans_idx = []
    
    # Each ttinfo structure is written as a four-byte value
    # for tt_gmtoff  of  type long,  in  a  standard  byte
    # order, followed  by a one-byte value for tt_isdst
    # and a one-byte  value  for  tt_abbrind.   In  each
    # structure, tt_gmtoff  gives  the  number  of
    # seconds to be added to UTC, tt_isdst tells whether
    # tm_isdst should be set by  localtime(3),  and
    # tt_abbrind serves  as an index into the array of
    # time zone abbreviation characters that follow the
    # ttinfo structure(s) in the file.

    ttinfo = []

    for i in range(typecnt):
      ttinfo.append(struct.unpack(">lbb", fileobj.read(6)))

    abbr = fileobj.read(charcnt)

    # Then there are tzh_leapcnt pairs of four-byte
    # values, written in  standard byte  order;  the
    # first  value  of  each pair gives the time (as
    # returned by time(2)) at which a leap second
    # occurs;  the  second  gives the  total  number of
    # leap seconds to be applied after the given time.
    # The pairs of values are sorted in ascending order
    # by time.

    # Not used, for now
    if leapcnt:
      leap = struct.unpack(">%dl" % leapcnt*2,
                 fileobj.read(leapcnt*8))

    # Then there are tzh_ttisstdcnt standard/wall
    # indicators, each stored as a one-byte value;
    # they tell whether the transition times associated
    # with local time types were specified as standard
    # time or wall clock time, and are used when
    # a time zone file is used in handling POSIX-style
    # time zone environment variables.

    if ttisstdcnt:
      isstd = struct.unpack(">%db" % ttisstdcnt,
                  fileobj.read(ttisstdcnt))

    # Finally, there are tzh_ttisgmtcnt UTC/local
    # indicators, each stored as a one-byte value;
    # they tell whether the transition times associated
    # with local time types were specified as UTC or
    # local time, and are used when a time zone file
    # is used in handling POSIX-style time zone envi-
    # ronment variables.

    if ttisgmtcnt:
      isgmt = struct.unpack(">%db" % ttisgmtcnt,
                  fileobj.read(ttisgmtcnt))

    # ** Everything has been read **

    # Build ttinfo list
    self._ttinfo_list = []
    for i in range(typecnt):
      tti = _ttinfo()
      tti.offset = ttinfo[i][0]
      tti.delta = datetime.timedelta(seconds=ttinfo[i][0])
      tti.isdst = ttinfo[i][1]
      tti.abbr = abbr[ttinfo[i][2]:abbr.find('\x00', ttinfo[i][2])]
      tti.isstd = (ttisstdcnt > i and isstd[i] != 0)
      tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0)
      self._ttinfo_list.append(tti)

    # Replace ttinfo indexes for ttinfo objects.
    trans_idx = []
    for idx in self._trans_idx:
      trans_idx.append(self._ttinfo_list[idx])
    self._trans_idx = tuple(trans_idx)

    # Set standard, dst, and before ttinfos. before will be
    # used when a given time is before any transitions,
    # and will be set to the first non-dst ttinfo, or to
    # the first dst, if all of them are dst.
    self._ttinfo_std = None
    self._ttinfo_dst = None
    self._ttinfo_before = None
    if self._ttinfo_list:
      if not self._trans_list:
        self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0]
      else:
        for i in range(timecnt-1,-1,-1):
          tti = self._trans_idx[i]
          if not self._ttinfo_std and not tti.isdst:
            self._ttinfo_std = tti
          elif not self._ttinfo_dst and tti.isdst:
            self._ttinfo_dst = tti
          if self._ttinfo_std and self._ttinfo_dst:
            break
        else:
          if self._ttinfo_dst and not self._ttinfo_std:
            self._ttinfo_std = self._ttinfo_dst

        for tti in self._ttinfo_list:
          if not tti.isdst:
            self._ttinfo_before = tti
            break
        else:
          self._ttinfo_before = self._ttinfo_list[0]

    # Now fix transition times to become relative to wall time.
    #
    # I'm not sure about this. In my tests, the tz source file
    # is setup to wall time, and in the binary file isstd and
    # isgmt are off, so it should be in wall time. OTOH, it's
    # always in gmt time. Let me know if you have comments
    # about this.
    laststdoffset = 0
    self._trans_list = list(self._trans_list)
    for i in range(len(self._trans_list)):
      tti = self._trans_idx[i]
      if not tti.isdst:
        # This is std time.
        self._trans_list[i] += tti.offset
        laststdoffset = tti.offset
      else:
        # This is dst time. Convert to std.
        self._trans_list[i] += laststdoffset
    self._trans_list = tuple(self._trans_list)

  def _find_ttinfo(self, dt, laststd=0):
    timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400
           + dt.hour * 3600
           + dt.minute * 60
           + dt.second)
    idx = 0
    for trans in self._trans_list:
      if timestamp < trans:
        break
      idx += 1
    else:
      return self._ttinfo_std
    if idx == 0:
      return self._ttinfo_before
    if laststd:
      while idx > 0:
        tti = self._trans_idx[idx-1]
        if not tti.isdst:
          return tti
        idx -= 1
      else:
        return self._ttinfo_std
    else:
      return self._trans_idx[idx-1]

  def utcoffset(self, dt):
    if not self._ttinfo_std:
      return ZERO
    return self._find_ttinfo(dt).delta

  def dst(self, dt):
    if not self._ttinfo_dst:
      return ZERO
    tti = self._find_ttinfo(dt)
    if not tti.isdst:
      return ZERO

    # The documentation says that utcoffset()-dst() must
    # be constant for every dt.
    return self._find_ttinfo(dt, laststd=1).delta-tti.delta

    # An alternative for that would be:
    #
    # return self._ttinfo_dst.offset-self._ttinfo_std.offset
    #
    # However, this class stores historical changes in the
    # dst offset, so I belive that this wouldn't be the right
    # way to implement this.
    
  def tzname(self, dt):
    if not self._ttinfo_std:
      return None
    return self._find_ttinfo(dt).abbr

  def __eq__(self, other):
    if not isinstance(other, TzFile):
      return False
    return (self._trans_list == other._trans_list and
        self._trans_idx == other._trans_idx and
        self._ttinfo_list == other._ttinfo_list)

  def __ne__(self, other):
    return not self.__eq__(other)


  def __repr__(self):
    return "%s(%s)" % (self.__class__.__name__, `self._s`)
    
TzFileS = ["/etc/localtime", "localtime"]
TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"]

def _posix_timezone(name):
  tz = None
  assert name!=None, "No timezone name was provided"
  
  if name and name[0] == ":":
    name = name[:-1]
  for path in TZPATHS:
    filepath = os.path.join(path, name)
    if not os.path.isfile(filepath):
      filepath = filepath.replace(' ','_')
      if not os.path.isfile(filepath):
        continue
    try:
      tz = TzFile(filepath)
      break
    except (IOError, OSError, ValueError):
      pass
  else:
    if name in ("GMT", "UTC"):
      tz = FixedOffset(0,"UTC")
  
  return tz
  
################################################################################
#                Non-Posix (Windows et al) section                             #
################################################################################

class DynamicOffset(datetime.tzinfo):
    """
    DST zones that starts on a day in a month that can be described:
        first <day> of a month
        second <day> of a month
        last <day> of a month
        next to last <day> of a month
        where <day> is the number datetime.weekday() uses
    """

    def _get_dst_transition_day(self,dt,day,num):
        """"
        dt is the date we use to find the day
        day is the number of day. Same definition as datetime.weekday()
        if num is 1, then we are looking for the first <day> of the month
        if num is 2, then we are looking for the second <day> of the month
        if num is -1, then we are looking for the last <day> of previous month
        if num is -2, then we are looking for next to last <day> of previous month
        """
        assert num <=2 and num != 0 and num >= -2, "Ryfm!"
        assert day >= 0 and day <= 6, "Illegal day number (hint: they start at 0)"

        if num < 0:
            # get to next month
            this_month = dt.month
            while this_month == dt.month:
                dt += datetime.timedelta(14)
            # get back to previous month
            dt -= datetime.timedelta(dt.day)
            # We are now at the last day of this month

            # find the previous <day>
            days_to_go = day - dt.weekday()
            if days_to_go > 0:
                days_to_go -= 7
            if days_to_go != 0:
                dt += datetime.timedelta(days_to_go)
            if num==-2:
                dt -= datetime.timedelta(7)
            return dt
        else:
            days_to_go = day - dt.weekday()
            if days_to_go < 0:
                days_to_go += 7
            if days_to_go:
                dt += datetime.timedelta(days_to_go)
            if num==2:
                dt += datetime.timedelta(7)
            return dt

    def __init__(self, minutes, reprname, stdname, dstname, dstStart, dstEnd, \
        startDay, startDayNum, endDay, endDayNum):

        self.stdoffset = datetime.timedelta(minutes=minutes)
        self.reprname = reprname
        self.stdname = stdname
        self.dstname = dstname
        self.dstStart = dstStart
        self.dstEnd = dstEnd
        self.startDay = startDay
        self.startDayNum = startDayNum
        self.endDay = endDay
        self.endDayNum = endDayNum

    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):
        """
        Returns the DST offset.
        Note that this method accepts naive datetimes in dt.
        """
        if dt is None:
            return ZERO
        #assert dt.tzinfo is self

        start = self._get_dst_transition_day(
                    self.dstStart.replace(year=dt.year),
                    self.startDay, self.startDayNum)
        end = self._get_dst_transition_day(
                    self.dstEnd.replace(year=dt.year),
                    self.endDay, self.endDayNum)

        if start < end:
            # 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
        else:
            #Compensate for those "down below"
            if end <= dt.replace(tzinfo=None) < start:
                return ZERO
            else:
                return HOUR

# DynamicOffset

def _setup():
    global _tz

    ############################################################################
    # US Timezones
    # In the US, DST starts at 2am (standard time) on the first Sunday in April.
    # and ends at 2am (DST time; 3am standard time) on the last Sunday of Oct.

    dststart = datetime.datetime(1, 4, 1, 2)
    dstend = datetime.datetime(1, 10, 1, 2)

    _tz["UTC"] = FixedOffset(0,"UTC")
    _tz["US/Eastern"]  = DynamicOffset(-5*60, "US/Eastern" , "EST", "EDT",
                                       dststart, dstend, 6, 1, 6, -1)
    _tz["US/Central"]  = DynamicOffset(-6*60, "US/Central" , "CST", "CDT",
                                       dststart, dstend, 6, 1, 6, -1)
    _tz["US/Mountain"] = DynamicOffset(-7*60, "US/Mountain", "MST", "MDT",
                                       dststart, dstend, 6, 1, 6, -1)
    _tz["US/Pacific"]  = DynamicOffset(-8*60, "US/Pacific" , "PST", "PDT",
                                       dststart, dstend, 6, 1, 6, -1)

    ############################################################################
    # London Timezone
    # GMT starts last Sunday of March at 01:00 st
    # BST starts last Sunday of October at 02:00 dst (01:00 st)

    dststart = datetime.datetime(1, 3, 1, 1)
    dstend = datetime.datetime(1, 10, 1, 2)

    _tz['Europe/London'] = DynamicOffset(0, 'Europe/London', 'GMT', 'BST',
                                           dststart, dstend, 6, -1, 6, -1)

    ############################################################################
    # CET Timezones
    # CET starts the last Sunday of March at 02:00 st
    # CEST starts the last Sunday of October 03:00 dst (02:00 st)

    dststart = datetime.datetime(1, 3, 1, 2)
    dstend   = datetime.datetime(1, 10, 1, 3)

    _tz['CET'] = DynamicOffset(1*60, 'CET', 'CET', 'CST',
                               dststart, dstend, 6, -1, 6, -1)
    _tz['Europe/Madrid'] = \
        DynamicOffset(1*60, 'Europe/Madrid', 'CET', 'CEST',
                      dststart, dstend, 6, -1, 6, -1)
    _tz['Europe/Copenhagen'] = \
        DynamicOffset(1*60, 'Europe/Copenhagen', 'CET', 'CEST',
                      dststart, dstend, 6, -1, 6, -1)

    _tz['Europe/Oslo'] = \
        DynamicOffset(1*60, 'Europe/Oslo', 'CET', 'CEST',
                      dststart,dstend, 6, -1, 6, -1)
    _tz['Europe/Paris'] = \
        DynamicOffset(1*60, 'Europe/Paris', 'CET', 'CEST',
                      dststart, dstend, 6, -1, 6, -1)
    _tz['Europe/Berlin'] = \
        DynamicOffset(1*60, 'Europe/Berlin', 'CET', 'CEST',
                      dststart, dstend, 6, -1,6, -1)
    _tz['Europe/Amsterdam'] = \
        DynamicOffset(1*60, 'Europe/Amsterdam', 'CET', 'CEST',
                      dststart, dstend, 6, -1, 6, -1)
    _tz['Europe/Brussels'] = \
        DynamicOffset(1*60, 'Europe/Brussels', 'CET', 'CEST',
                      dststart, dstend, 6, -1, 6, -1)
    _tz['Europe/Stockholm'] = \
        DynamicOffset(1*60, 'Europe/Stockholm', 'CET', 'CEST',
                      dststart, dstend, 6, -1, 6, -1)

    ############################################################################
    # EET Timezones
    # EET starts the last Sunday of March at 03:00 st
    # EEST starts the last Sunday of October 04:00 dst (03:00 st)

    dststart = datetime.datetime(1, 3, 1, 3)
    dstend = datetime.datetime(1, 10, 1, 4)
    _tz['EET'] = DynamicOffset(2*60, 'EET', 'EET', 'EEST',
                               dststart, dstend, 6, -1, 6, -1)
    _tz['Europe/Helsinki'] = \
        DynamicOffset(2*60, 'Europe/Helsinki', 'EEST', 'EET',
                      dststart, dstend, 6, -1, 6, -1)

    ############################################################################
    # Australia/Sydney Timezone
    # DST starts the last Sunday of October
    # DST ends the last Sunday of March

    dststart = datetime.datetime(1, 10, 1, 2)
    dstend  = datetime.datetime(1, 3, 1, 3)

    _tz['Australia/Sydney'] = \
        DynamicOffset(10*60, 'Australia/Sydney', 'EST', 'EST',
                      dststart, dstend, 6, -1, 6, -1)
    _tz['Australia/Perth'] = FixedOffset(8*60,"Australia/Perth")
    #Australia/Adelaid ??
    #Australia/West ??
    _tz['Australia/Broken_Hill'] = \
        DynamicOffset(9*60+30, 'Australia/Broken_Hill', 'EST', 'EST',
                      dststart, dstend, 6, -1, 6, -1)
    _tz['Australia/Darwin'] = FixedOffset(9*60+30,"Australia/Darwin")
    _tz['Australia/North'] = FixedOffset(9*60+30,"Australia/North")
    _tz['Australia/South'] = \
        DynamicOffset(9*60+30, 'Australia/South', 'EST', 'EST',
                      dststart, dstend, 6, -1, 6, -1)
    _tz['Australia/Yancowinna'] = \
        DynamicOffset(9*60+30, 'Australia/Yancowinna', 'EST', 'EST',
                      dststart, dstend, 6, -1, 6, -1)

    ############################################################################
    # Brasil timezone 
    # BRT starts a Sunday (seemingly in the middle of the month?) of Feb at 00:00 st
    # BRST ends a Sunday (seemingly in the middle of the month?) of October 0:00 dst (01:00 st)

    dststart = datetime.datetime(1, 10, 1, 23, 59, 59, 999999)
    dstend  = datetime.datetime(1, 3, 1, 23, 59, 59, 999999)
    #_tz['BRT'] = TzDstLastSunday(-2, 'BRT', 'BRT', 'BRST', dststart, dstend)
    _tz['Brazil/DeNoronha']  = FixedOffset(-2*60,"Brazil/DeNoronha")
    _tz["Brazil/West"]       = FixedOffset(-4*60,"Brazil/West")
    #_tz["Brazil/East"]       = TzDstLastSaturday(-3, 'Brazil/East', 'BRT', 'BRST', dststart, dstend)
    _tz["Brazil/Acre"]       = FixedOffset(-5*60,"Brazil/Acre")

if os.name != "posix":
  global _tz
  _tz = {}
  _setup()

def _win_timezone(tz_name):
    """
    Returns a tzinfo implementation by name,
    only a few are implemented, if you need more (and are lucky enough to need
    a "simple" timezone like those described here) just copy&paste
    """
    assert _tz.has_key(tz_name), "Undefined timezone"
    return _tz[tz_name] 
      
# --------------  Unit Tests  -------------- #

from datetime import datetime

using_unittest2=False
try:
  import unittest2 as unittest
  using_unittest2=True
except:
  import unittest

class Timezone_UnitTest(unittest.TestCase):

  ONE_HOUR = datetime.timedelta(hours=1)

  def toStr(self,tdiff):
    """ returns -1:00:00 instead of -1 day, 23:00:00"""
    if tdiff.days < 0:
        return "-" + str(abs(tdiff))
    else:
        return str(tdiff)

  def vt(self, date, tz, expected):
    """
    Verifies the DST transition. One hour before and after.
    When the off-by-one-hour-when-DST bug of TzFile is fixed
    i will go back to one second before and after tests.
    """
    tz = timezone(tz)
    date.replace(tzinfo=tz)
    date = date - self.ONE_HOUR
    rv = self.toStr(tz.utcoffset(date))
    date = date + self.ONE_HOUR
    date = date + self.ONE_HOUR
    rv = (rv, self.toStr(tz.utcoffset(date)))
    assert rv==expected, str(rv) + "!=" + str(expected)

  # test 0-49 tests the CET/CEST timezones
  def test000(self): self.vt(d(2000,03,26,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test001(self): self.vt(d(2000,10,29,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test002(self): self.vt(d(2001,03,25,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test003(self): self.vt(d(2001,10,28,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test004(self): self.vt(d(2002,03,31,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test005(self): self.vt(d(2002,10,27,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test006(self): self.vt(d(2003,03,30,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test007(self): self.vt(d(2003,10,26,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test008(self): self.vt(d(2004,03,28,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test009(self): self.vt(d(2004,10,31,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test010(self): self.vt(d(2005,03,27,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test011(self): self.vt(d(2005,10,30,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test012(self): self.vt(d(2006,03,26,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test013(self): self.vt(d(2006,10,29,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test014(self): self.vt(d(2007,03,25,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test015(self): self.vt(d(2007,10,28,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test016(self): self.vt(d(2008,03,30,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test017(self): self.vt(d(2008,10,26,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test018(self): self.vt(d(2009,03,29,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test019(self): self.vt(d(2009,10,25,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test020(self): self.vt(d(2010,03,28,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test021(self): self.vt(d(2010,10,31,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test022(self): self.vt(d(2011,03,27,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test023(self): self.vt(d(2011,10,30,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test024(self): self.vt(d(2012,03,25,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test025(self): self.vt(d(2012,10,28,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test026(self): self.vt(d(2013,03,31,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test027(self): self.vt(d(2013,10,27,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test028(self): self.vt(d(2014,03,30,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test029(self): self.vt(d(2014,10,26,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test030(self): self.vt(d(2015,03,29,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test031(self): self.vt(d(2015,10,25,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test032(self): self.vt(d(2016,03,27,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test033(self): self.vt(d(2016,10,30,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test034(self): self.vt(d(2017,03,26,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test035(self): self.vt(d(2017,10,29,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test036(self): self.vt(d(2018,03,25,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test037(self): self.vt(d(2018,10,28,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test038(self): self.vt(d(2019,03,31,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test039(self): self.vt(d(2019,10,27,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test040(self): self.vt(d(2020,03,29,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test041(self): self.vt(d(2020,10,25,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test042(self): self.vt(d(2021,03,28,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test043(self): self.vt(d(2021,10,31,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test044(self): self.vt(d(2022,03,27,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test045(self): self.vt(d(2022,10,30,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test046(self): self.vt(d(2023,03,26,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test047(self): self.vt(d(2023,10,29,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))
  def test048(self): self.vt(d(2024,03,31,01,59,59),'Europe/Stockholm',('1:00:00','2:00:00'))
  def test049(self): self.vt(d(2024,10,27,02,59,59),'Europe/Stockholm',('2:00:00','1:00:00'))

  # test 50-99 tests the GMT timezones
  def test050(self): self.vt(d(2000,03,26,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test051(self): self.vt(d(2000,10,29,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test052(self): self.vt(d(2001,03,25,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test053(self): self.vt(d(2001,10,28,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test054(self): self.vt(d(2002,03,31,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test055(self): self.vt(d(2002,10,27,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test056(self): self.vt(d(2003,03,30,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test057(self): self.vt(d(2003,10,26,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test058(self): self.vt(d(2004,03,28,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test059(self): self.vt(d(2004,10,31,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test060(self): self.vt(d(2005,03,27,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test061(self): self.vt(d(2005,10,30,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test062(self): self.vt(d(2006,03,26,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test063(self): self.vt(d(2006,10,29,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test064(self): self.vt(d(2007,03,25,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test065(self): self.vt(d(2007,10,28,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test066(self): self.vt(d(2008,03,30,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test067(self): self.vt(d(2008,10,26,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test068(self): self.vt(d(2009,03,29,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test069(self): self.vt(d(2009,10,25,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test070(self): self.vt(d(2010,03,28,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test071(self): self.vt(d(2010,10,31,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test072(self): self.vt(d(2011,03,27,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test073(self): self.vt(d(2011,10,30,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test074(self): self.vt(d(2012,03,25,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test075(self): self.vt(d(2012,10,28,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test076(self): self.vt(d(2013,03,31,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test077(self): self.vt(d(2013,10,27,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test078(self): self.vt(d(2014,03,30,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test079(self): self.vt(d(2014,10,26,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test080(self): self.vt(d(2015,03,29,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test081(self): self.vt(d(2015,10,25,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test082(self): self.vt(d(2016,03,27,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test083(self): self.vt(d(2016,10,30,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test084(self): self.vt(d(2017,03,26,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test085(self): self.vt(d(2017,10,29,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test086(self): self.vt(d(2018,03,25,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test087(self): self.vt(d(2018,10,28,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test088(self): self.vt(d(2019,03,31,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test089(self): self.vt(d(2019,10,27,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test090(self): self.vt(d(2020,03,29,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test091(self): self.vt(d(2020,10,25,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test092(self): self.vt(d(2021,03,28,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test093(self): self.vt(d(2021,10,31,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test094(self): self.vt(d(2022,03,27,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test095(self): self.vt(d(2022,10,30,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test096(self): self.vt(d(2023,03,26,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test097(self): self.vt(d(2023,10,29,01,59,59),'Europe/London',('1:00:00','0:00:00'))
  def test098(self): self.vt(d(2024,03,31,00,59,59),'Europe/London',('0:00:00','1:00:00'))
  def test099(self): self.vt(d(2024,10,27,01,59,59),'Europe/London',('1:00:00','0:00:00'))

  # test 100-149 tests the US/Eastern timezone
  def test100(self): self.vt(d(2001,4,1,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test101(self): self.vt(d(2001,10,28,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test102(self): self.vt(d(2002,10,27,1,59,59),'US/Mountain',('-6:00:00','-7:00:00'))
  def test103(self): self.vt(d(2003,4,6,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test104(self): self.vt(d(2004,4,4,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test105(self): self.vt(d(2004,10,31,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test106(self): self.vt(d(2006,4,2,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test107(self): self.vt(d(2006,10,29,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test108(self): self.vt(d(2007,4,1,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test109(self): self.vt(d(2007,10,28,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test110(self): self.vt(d(2008,4,6,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test111(self): self.vt(d(2009,4,5,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test112(self): self.vt(d(2009,10,25,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test113(self): self.vt(d(2011,4,3,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test114(self): self.vt(d(2011,10,30,1,59,59),'US/Central',('-5:00:00','-6:00:00'))
  def test115(self): self.vt(d(2012,4,1,1,59,59),'US/Mountain',('-7:00:00','-6:00:00'))
  def test116(self): self.vt(d(2012,10,28,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test117(self): self.vt(d(2013,4,7,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test118(self): self.vt(d(2014,4,6,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test119(self): self.vt(d(2014,10,26,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test120(self): self.vt(d(2015,10,25,1,59,59),'US/Pacific',('-7:00:00','-8:00:00'))
  def test121(self): self.vt(d(2016,4,3,1,59,59),'US/Pacific',('-8:00:00','-7:00:00'))
  def test122(self): self.vt(d(2016,10,30,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test123(self): self.vt(d(2017,4,2,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test124(self): self.vt(d(2017,10,29,1,59,59),'US/Central',('-5:00:00','-6:00:00'))
  def test125(self): self.vt(d(2019,4,7,1,59,59),'US/Central',('-6:00:00','-5:00:00'))
  def test126(self): self.vt(d(2019,10,27,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test127(self): self.vt(d(2020,10,25,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test128(self): self.vt(d(2021,4,4,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test129(self): self.vt(d(2021,10,31,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test130(self): self.vt(d(2022,4,3,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test131(self): self.vt(d(2022,10,30,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test132(self): self.vt(d(2024,4,7,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test133(self): self.vt(d(2024,10,27,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test134(self): self.vt(d(2025,10,26,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test135(self): self.vt(d(2026,4,5,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test136(self): self.vt(d(2027,4,4,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test137(self): self.vt(d(2027,10,31,1,59,59),'US/Pacific',('-7:00:00','-8:00:00'))
  def test138(self): self.vt(d(2029,4,1,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test139(self): self.vt(d(2029,10,28,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test140(self): self.vt(d(2030,10,27,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test141(self): self.vt(d(2031,4,6,1,59,59),'US/Mountain',('-7:00:00','-6:00:00'))
  def test142(self): self.vt(d(2032,4,4,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test143(self): self.vt(d(2032,10,31,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test144(self): self.vt(d(2034,4,2,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test145(self): self.vt(d(2034,10,29,1,59,59),'US/Eastern',('-4:00:00','-5:00:00'))
  def test146(self): self.vt(d(2035,4,1,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test147(self): self.vt(d(2035,10,28,1,59,59),'US/Mountain',('-6:00:00','-7:00:00'))
  def test148(self): self.vt(d(2036,4,6,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))
  def test149(self): self.vt(d(2037,4,5,1,59,59),'US/Eastern',('-5:00:00','-4:00:00'))

  # test 150-199 tests the Europe/Helsinki timezone
  def test150(self): self.vt(d(2000,3,26,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test151(self): self.vt(d(2001,10,28,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test152(self): self.vt(d(2002,3,31,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test153(self): self.vt(d(2002,10,27,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test154(self): self.vt(d(2004,3,28,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test155(self): self.vt(d(2004,10,31,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test156(self): self.vt(d(2005,3,27,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test157(self): self.vt(d(2006,10,29,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test158(self): self.vt(d(2007,3,25,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test159(self): self.vt(d(2007,10,28,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test160(self): self.vt(d(2009,3,29,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test161(self): self.vt(d(2009,10,25,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test162(self): self.vt(d(2010,3,28,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test163(self): self.vt(d(2011,10,30,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test164(self): self.vt(d(2012,3,25,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test165(self): self.vt(d(2012,10,28,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test166(self): self.vt(d(2014,3,30,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test167(self): self.vt(d(2014,10,26,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test168(self): self.vt(d(2015,3,29,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test169(self): self.vt(d(2015,10,25,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test170(self): self.vt(d(2016,10,30,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test171(self): self.vt(d(2017,3,26,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test172(self): self.vt(d(2017,10,29,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test173(self): self.vt(d(2018,3,25,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test174(self): self.vt(d(2019,3,31,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test175(self): self.vt(d(2019,10,27,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test176(self): self.vt(d(2020,3,29,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test177(self): self.vt(d(2020,10,25,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test178(self): self.vt(d(2021,10,31,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test179(self): self.vt(d(2022,3,27,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test180(self): self.vt(d(2022,10,30,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test181(self): self.vt(d(2023,3,26,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test182(self): self.vt(d(2024,3,31,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test183(self): self.vt(d(2024,10,27,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test184(self): self.vt(d(2025,3,30,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test185(self): self.vt(d(2025,10,26,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test186(self): self.vt(d(2027,3,28,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test187(self): self.vt(d(2027,10,31,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test188(self): self.vt(d(2028,3,26,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test189(self): self.vt(d(2029,10,28,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test190(self): self.vt(d(2030,3,31,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test191(self): self.vt(d(2030,10,27,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test192(self): self.vt(d(2032,3,28,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test193(self): self.vt(d(2032,10,31,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test194(self): self.vt(d(2033,3,27,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test195(self): self.vt(d(2034,10,29,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test196(self): self.vt(d(2035,3,25,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test197(self): self.vt(d(2035,10,28,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))
  def test198(self): self.vt(d(2037,3,29,2,59,59),'Europe/Helsinki',('2:00:00','3:00:00'))
  def test199(self): self.vt(d(2037,10,25,3,59,59),'Europe/Helsinki',('3:00:00','2:00:00'))

  # test 200-249 tests the Australia/Sydney timezone
  def test200(self): self.vt(d(2000,03,26,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  # Test 201 will fail on the windows implementation, Chris said something about DST
  # were adjusted for the Olympics or something, so those simple rules won't work
  #def test201(self): self.vt(d(2000,8,27,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test202(self): self.vt(d(2001,03,25,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test203(self): self.vt(d(2001,10,28,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test204(self): self.vt(d(2002,03,31,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test205(self): self.vt(d(2002,10,27,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test206(self): self.vt(d(2003,03,30,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test207(self): self.vt(d(2003,10,26,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test208(self): self.vt(d(2004,03,28,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test209(self): self.vt(d(2004,10,31,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test210(self): self.vt(d(2005,03,27,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test211(self): self.vt(d(2005,10,30,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test212(self): self.vt(d(2006,03,26,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test213(self): self.vt(d(2006,10,29,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test214(self): self.vt(d(2007,03,25,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test215(self): self.vt(d(2007,10,28,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test216(self): self.vt(d(2008,03,30,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test217(self): self.vt(d(2008,10,26,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test218(self): self.vt(d(2009,03,29,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test219(self): self.vt(d(2009,10,25,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test220(self): self.vt(d(2010,03,28,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test221(self): self.vt(d(2010,10,31,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test222(self): self.vt(d(2011,03,27,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test223(self): self.vt(d(2011,10,30,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test224(self): self.vt(d(2012,03,25,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test225(self): self.vt(d(2012,10,28,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test226(self): self.vt(d(2013,03,31,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test227(self): self.vt(d(2013,10,27,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test228(self): self.vt(d(2014,03,30,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test229(self): self.vt(d(2014,10,26,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test230(self): self.vt(d(2015,03,29,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test231(self): self.vt(d(2015,10,25,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test232(self): self.vt(d(2016,03,27,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test233(self): self.vt(d(2016,10,30,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test234(self): self.vt(d(2017,03,26,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test235(self): self.vt(d(2017,10,29,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test236(self): self.vt(d(2018,03,25,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test237(self): self.vt(d(2018,10,28,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test238(self): self.vt(d(2019,03,31,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test239(self): self.vt(d(2019,10,27,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test240(self): self.vt(d(2020,03,29,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test241(self): self.vt(d(2020,10,25,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test242(self): self.vt(d(2021,03,28,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test243(self): self.vt(d(2021,10,31,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test244(self): self.vt(d(2022,03,27,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test245(self): self.vt(d(2022,10,30,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test246(self): self.vt(d(2023,03,26,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test247(self): self.vt(d(2023,10,29,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))
  def test248(self): self.vt(d(2024,03,31,02,59,59),'Australia/Sydney',('11:00:00','10:00:00'))
  def test249(self): self.vt(d(2024,10,27,01,59,59),'Australia/Sydney',('10:00:00','11:00:00'))

  # test 200-249 tests the Australia/9.5 timezones
  def test250(self): self.vt(d(2000,03,26,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test251(self): self.vt(d(2000,10,29,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test252(self): self.vt(d(2001,03,25,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test253(self): self.vt(d(2001,10,28,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test254(self): self.vt(d(2002,03,31,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test255(self): self.vt(d(2002,10,27,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test256(self): self.vt(d(2003,03,30,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test257(self): self.vt(d(2003,10,26,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test258(self): self.vt(d(2004,03,28,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test259(self): self.vt(d(2004,10,31,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test260(self): self.vt(d(2005,03,27,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test261(self): self.vt(d(2005,10,30,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test262(self): self.vt(d(2006,03,26,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test263(self): self.vt(d(2006,10,29,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test264(self): self.vt(d(2007,03,25,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test265(self): self.vt(d(2007,10,28,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test266(self): self.vt(d(2008,03,30,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test267(self): self.vt(d(2008,10,26,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test268(self): self.vt(d(2009,03,29,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test269(self): self.vt(d(2009,10,25,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test270(self): self.vt(d(2010,03,28,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test271(self): self.vt(d(2010,10,31,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test272(self): self.vt(d(2011,03,27,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test273(self): self.vt(d(2011,10,30,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test274(self): self.vt(d(2012,03,25,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test275(self): self.vt(d(2012,10,28,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test276(self): self.vt(d(2013,03,31,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test277(self): self.vt(d(2013,10,27,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test278(self): self.vt(d(2014,03,30,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test279(self): self.vt(d(2014,10,26,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test280(self): self.vt(d(2015,03,29,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test281(self): self.vt(d(2015,10,25,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test282(self): self.vt(d(2016,03,27,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test283(self): self.vt(d(2016,10,30,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test284(self): self.vt(d(2017,03,26,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test285(self): self.vt(d(2017,10,29,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test286(self): self.vt(d(2018,03,25,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test287(self): self.vt(d(2018,10,28,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test288(self): self.vt(d(2019,03,31,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test289(self): self.vt(d(2019,10,27,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test290(self): self.vt(d(2020,03,29,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test291(self): self.vt(d(2020,10,25,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test292(self): self.vt(d(2021,03,28,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test293(self): self.vt(d(2021,10,31,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test294(self): self.vt(d(2022,03,27,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test295(self): self.vt(d(2022,10,30,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test296(self): self.vt(d(2023,03,26,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test297(self): self.vt(d(2023,10,29,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))
  def test298(self): self.vt(d(2024,03,31,02,59,59),'Australia/Broken_Hill',('10:30:00','9:30:00'))
  def test299(self): self.vt(d(2024,10,27,01,59,59),'Australia/Broken_Hill',('9:30:00','10:30:00'))


if using_unittest2 or __name__ == '__main__':
  
  # Not all unit tests work with the unix TZ database
  unittest.main()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.