Skip to content

Commit

Permalink
Merge pull request #141 from pganssle/labrys-tzwin
Browse files Browse the repository at this point in the history
Fix tzwin import issue
  • Loading branch information
pganssle committed Nov 1, 2015
2 parents ed975b1 + 43f1a27 commit b46e721
Show file tree
Hide file tree
Showing 8 changed files with 600 additions and 261 deletions.
104 changes: 52 additions & 52 deletions dateutil/relativedelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,75 +40,75 @@ def __repr__(self):

class relativedelta(object):
"""
The relativedelta type is based on the specification of the excellent
work done by M.-A. Lemburg in his
`mx.DateTime <http://www.egenix.com/files/python/mxDateTime.html>`_ extension.
However, notice that this type does *NOT* implement the same algorithm as
his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.
The relativedelta type is based on the specification of the excellent
work done by M.-A. Lemburg in his
`mx.DateTime <http://www.egenix.com/files/python/mxDateTime.html>`_ extension.
However, notice that this type does *NOT* implement the same algorithm as
his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.
There are two different ways to build a relativedelta instance. The
first one is passing it two date/datetime classes::
There are two different ways to build a relativedelta instance. The
first one is passing it two date/datetime classes::
relativedelta(datetime1, datetime2)
relativedelta(datetime1, datetime2)
The second one is passing it any number of the following keyword arguments::
The second one is passing it any number of the following keyword arguments::
relativedelta(arg1=x,arg2=y,arg3=z...)
relativedelta(arg1=x,arg2=y,arg3=z...)
year, month, day, hour, minute, second, microsecond:
Absolute information (argument is singular); adding or subtracting a
relativedelta with absolute information does not perform an aritmetic
operation, but rather REPLACES the corresponding value in the
original datetime with the value(s) in relativedelta.
year, month, day, hour, minute, second, microsecond:
Absolute information (argument is singular); adding or subtracting a
relativedelta with absolute information does not perform an aritmetic
operation, but rather REPLACES the corresponding value in the
original datetime with the value(s) in relativedelta.
years, months, weeks, days, hours, minutes, seconds, microseconds:
Relative information, may be negative (argument is plural); adding
or subtracting a relativedelta with relative information performs
the corresponding aritmetic operation on the original datetime value
with the information in the relativedelta.
years, months, weeks, days, hours, minutes, seconds, microseconds:
Relative information, may be negative (argument is plural); adding
or subtracting a relativedelta with relative information performs
the corresponding aritmetic operation on the original datetime value
with the information in the relativedelta.
weekday:
One of the weekday instances (MO, TU, etc). These instances may
receive a parameter N, specifying the Nth weekday, which could
be positive or negative (like MO(+1) or MO(-2). Not specifying
it is the same as specifying +1. You can also use an integer,
where 0=MO.
weekday:
One of the weekday instances (MO, TU, etc). These instances may
receive a parameter N, specifying the Nth weekday, which could
be positive or negative (like MO(+1) or MO(-2). Not specifying
it is the same as specifying +1. You can also use an integer,
where 0=MO.
leapdays:
Will add given days to the date found, if year is a leap
year, and the date found is post 28 of february.
leapdays:
Will add given days to the date found, if year is a leap
year, and the date found is post 28 of february.
yearday, nlyearday:
Set the yearday or the non-leap year day (jump leap days).
These are converted to day/month/leapdays information.
yearday, nlyearday:
Set the yearday or the non-leap year day (jump leap days).
These are converted to day/month/leapdays information.
Here is the behavior of operations with relativedelta:
Here is the behavior of operations with relativedelta:
1. Calculate the absolute year, using the 'year' argument, or the
original datetime year, if the argument is not present.
1. Calculate the absolute year, using the 'year' argument, or the
original datetime year, if the argument is not present.
2. Add the relative 'years' argument to the absolute year.
2. Add the relative 'years' argument to the absolute year.
3. Do steps 1 and 2 for month/months.
3. Do steps 1 and 2 for month/months.
4. Calculate the absolute day, using the 'day' argument, or the
original datetime day, if the argument is not present. Then,
subtract from the day until it fits in the year and month
found after their operations.
4. Calculate the absolute day, using the 'day' argument, or the
original datetime day, if the argument is not present. Then,
subtract from the day until it fits in the year and month
found after their operations.
5. Add the relative 'days' argument to the absolute day. Notice
that the 'weeks' argument is multiplied by 7 and added to
'days'.
5. Add the relative 'days' argument to the absolute day. Notice
that the 'weeks' argument is multiplied by 7 and added to
'days'.
6. Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds,
microsecond/microseconds.
6. Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds,
microsecond/microseconds.
7. If the 'weekday' argument is present, calculate the weekday,
with the given (wday, nth) tuple. wday is the index of the
weekday (0-6, 0=Mon), and nth is the number of weeks to add
forward or backward, depending on its signal. Notice that if
the calculated date is already Monday, for example, using
(0, 1) or (0, -1) won't change the day.
7. If the 'weekday' argument is present, calculate the weekday,
with the given (wday, nth) tuple. wday is the index of the
weekday (0-6, 0=Mon), and nth is the number of weeks to add
forward or backward, depending on its signal. Notice that if
the calculated date is already Monday, for example, using
(0, 1) or (0, -1) won't change the day.
"""

def __init__(self, dt1=None, dt2=None,
Expand Down
149 changes: 149 additions & 0 deletions dateutil/test/test_imports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import sys

try:
import unittest2 as unittest
except ImportError:
import unittest


class ImportEasterTest(unittest.TestCase):
""" Test that dateutil.easter-related imports work properly """

def testEasterDirect(self):
import dateutil.easter

def testEasterFrom(self):
from dateutil import easter

def testEasterStar(self):
from dateutil.easter import easter


class ImportParserTest(unittest.TestCase):
""" Test that dateutil.parser-related imports work properly """
def testParserDirect(self):
import dateutil.parser

def testParserFrom(self):
from dateutil import parser

def testParserAll(self):
# All interface
from dateutil.parser import parse
from dateutil.parser import parserinfo

# Other public classes
from dateutil.parser import parser

for var in (parse, parserinfo, parser):
self.assertIsNot(var, None)


class ImportRelativeDeltaTest(unittest.TestCase):
""" Test that dateutil.relativedelta-related imports work properly """
def testRelativeDeltaDirect(self):
import dateutil.relativedelta

def testRelativeDeltaFrom(self):
from dateutil import relativedelta

def testRelativeDeltaAll(self):
from dateutil.relativedelta import relativedelta
from dateutil.relativedelta import MO, TU, WE, TH, FR, SA, SU

for var in (relativedelta, MO, TU, WE, TH, FR, SA, SU):
self.assertIsNot(var, None)

# In the public interface but not in all
from dateutil.relativedelta import weekday
self.assertIsNot(weekday, None)


class ImportRRuleTest(unittest.TestCase):
""" Test that dateutil.rrule related imports work properly """
def testRRuleDirect(self):
import dateutil.rrule

def testRRuleFrom(self):
from dateutil import rrule

def testRRuleAll(self):
from dateutil.rrule import rrule
from dateutil.rrule import rruleset
from dateutil.rrule import rrulestr
from dateutil.rrule import YEARLY, MONTHLY, WEEKLY, DAILY
from dateutil.rrule import HOURLY, MINUTELY, SECONDLY
from dateutil.rrule import MO, TU, WE, TH, FR, SA, SU

rr_all = (rrule, rruleset, rrulestr,
YEARLY, MONTHLY, WEEKLY, DAILY,
HOURLY, MINUTELY, SECONDLY,
MO, TU, WE, TH, FR, SA, SU)

for var in rr_all:
self.assertIsNot(var, None)

# In the public interface but not in all
from dateutil.rrule import weekday
self.assertIsNot(weekday, None)


class ImportTZTest(unittest.TestCase):
""" Test that dateutil.tz related imports work properly """
def testTzDirect(self):
import dateutil.tz

def testTzFrom(self):
from dateutil import tz

def testTzAll(self):
from dateutil.tz import tzutc
from dateutil.tz import tzoffset
from dateutil.tz import tzlocal
from dateutil.tz import tzfile
from dateutil.tz import tzrange
from dateutil.tz import tzstr
from dateutil.tz import tzical
from dateutil.tz import gettz
from dateutil.tz import tzwin
from dateutil.tz import tzwinlocal

tz_all = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
"tzstr", "tzical", "gettz"]

tz_all += ["tzwin", "tzwinlocal"] if sys.platform.startswith("win") else []
lvars = locals()

for var in tz_all:
self.assertIsNot(lvars[var], None)


@unittest.skipUnless(sys.platform.startswith('win'), "Requires Windows")
class ImportTZWinTest(unittest.TestCase):
""" Test that dateutil.tzwin related imports work properly """
def testTzwinDirect(self):
import dateutil.tzwin

def testTzwinFrom(self):
from dateutil import tzwin

def testTzwinStar(self):
tzwin_all = ["tzwin", "tzwinlocal"]


class ImportZoneInfoTest(unittest.TestCase):
def testZoneinfoDirect(self):
import dateutil.zoneinfo

def testZoneinfoFrom(self):
from dateutil import zoneinfo

def testZoneinfoStar(self):
from dateutil.zoneinfo import gettz
from dateutil.zoneinfo import gettz_db_metadata
from dateutil.zoneinfo import rebuild

zi_all = (gettz, gettz_db_metadata, rebuild)

for var in zi_all:
self.assertIsNot(var, None)
20 changes: 20 additions & 0 deletions dateutil/tz/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from .tz import *
from six import PY3

__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
"tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"]

def tzname_in_python2(namefunc):
"""Change unicode output into bytestrings in Python 2
tzname() API changed in Python 3. It used to return bytes, but was changed
to unicode strings
"""
def adjust_encoding(*args, **kwargs):
name = namefunc(*args, **kwargs)
if name is not None and not PY3:
name = name.encode()

return name

return adjust_encoding
23 changes: 2 additions & 21 deletions dateutil/tz.py → dateutil/tz/tz.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,20 @@
import os

from six import string_types, PY3
from .__init__ import tzname_in_python2

try:
from dateutil.tzwin import tzwin, tzwinlocal
from .win import tzwin, tzwinlocal
except ImportError:
tzwin = tzwinlocal = None

relativedelta = None
parser = None
rrule = None

__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
"tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"]


def tzname_in_python2(namefunc):
"""Change unicode output into bytestrings in Python 2
tzname() API changed in Python 3. It used to return bytes, but was changed
to unicode strings
"""
def adjust_encoding(*args, **kwargs):
name = namefunc(*args, **kwargs)
if name is not None and not PY3:
name = name.encode()

return name

return adjust_encoding

ZERO = datetime.timedelta(0)
EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal()


class tzutc(datetime.tzinfo):

def utcoffset(self, dt):
Expand Down

0 comments on commit b46e721

Please sign in to comment.