Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

agriconnect / pandas   python

Repository URL to install this package:

Version: 0.24.2 

/ tests / tseries / offsets / test_offsets.py

from datetime import date, datetime, timedelta
from distutils.version import LooseVersion

import numpy as np
import pytest

from pandas._libs.tslibs import (
    NaT, OutOfBoundsDatetime, Timestamp, conversion, timezones)
from pandas._libs.tslibs.frequencies import (
    INVALID_FREQ_ERR_MSG, get_freq_code, get_freq_str)
import pandas._libs.tslibs.offsets as liboffsets
import pandas.compat as compat
from pandas.compat import range
from pandas.compat.numpy import np_datetime64_compat

from pandas.core.indexes.datetimes import DatetimeIndex, _to_M8, date_range
from pandas.core.series import Series
import pandas.util.testing as tm

from pandas.io.pickle import read_pickle
from pandas.tseries.frequencies import _offset_map, get_offset
from pandas.tseries.holiday import USFederalHolidayCalendar
import pandas.tseries.offsets as offsets
from pandas.tseries.offsets import (
    FY5253, BDay, BMonthBegin, BMonthEnd, BQuarterBegin, BQuarterEnd,
    BusinessHour, BYearBegin, BYearEnd, CBMonthBegin, CBMonthEnd, CDay,
    CustomBusinessHour, DateOffset, Day, Easter, FY5253Quarter,
    LastWeekOfMonth, MonthBegin, MonthEnd, Nano, QuarterBegin, QuarterEnd,
    SemiMonthBegin, SemiMonthEnd, Tick, Week, WeekOfMonth, YearBegin, YearEnd)

from .common import assert_offset_equal, assert_onOffset


class WeekDay(object):
    # TODO: Remove: This is not used outside of tests
    MON = 0
    TUE = 1
    WED = 2
    THU = 3
    FRI = 4
    SAT = 5
    SUN = 6


####
# Misc function tests
####


def test_to_M8():
    valb = datetime(2007, 10, 1)
    valu = _to_M8(valb)
    assert isinstance(valu, np.datetime64)


#####
# DateOffset Tests
#####


class Base(object):
    _offset = None
    d = Timestamp(datetime(2008, 1, 2))

    timezones = [None, 'UTC', 'Asia/Tokyo', 'US/Eastern',
                 'dateutil/Asia/Tokyo', 'dateutil/US/Pacific']

    def _get_offset(self, klass, value=1, normalize=False):
        # create instance from offset class
        if klass is FY5253:
            klass = klass(n=value, startingMonth=1, weekday=1,
                          variation='last', normalize=normalize)
        elif klass is FY5253Quarter:
            klass = klass(n=value, startingMonth=1, weekday=1,
                          qtr_with_extra_week=1, variation='last',
                          normalize=normalize)
        elif klass is LastWeekOfMonth:
            klass = klass(n=value, weekday=5, normalize=normalize)
        elif klass is WeekOfMonth:
            klass = klass(n=value, week=1, weekday=5, normalize=normalize)
        elif klass is Week:
            klass = klass(n=value, weekday=5, normalize=normalize)
        elif klass is DateOffset:
            klass = klass(days=value, normalize=normalize)
        else:
            try:
                klass = klass(value, normalize=normalize)
            except Exception:
                klass = klass(normalize=normalize)
        return klass

    def test_apply_out_of_range(self, tz_naive_fixture):
        tz = tz_naive_fixture
        if self._offset is None:
            return

        # try to create an out-of-bounds result timestamp; if we can't create
        # the offset skip
        try:
            if self._offset in (BusinessHour, CustomBusinessHour):
                # Using 10000 in BusinessHour fails in tz check because of DST
                # difference
                offset = self._get_offset(self._offset, value=100000)
            else:
                offset = self._get_offset(self._offset, value=10000)

            result = Timestamp('20080101') + offset
            assert isinstance(result, datetime)
            assert result.tzinfo is None

            # Check tz is preserved
            t = Timestamp('20080101', tz=tz)
            result = t + offset
            assert isinstance(result, datetime)
            assert t.tzinfo == result.tzinfo

        except OutOfBoundsDatetime:
            raise
        except (ValueError, KeyError):
            # we are creating an invalid offset
            # so ignore
            pass

    def test_offsets_compare_equal(self):
        # root cause of GH#456: __ne__ was not implemented
        if self._offset is None:
            return
        offset1 = self._offset()
        offset2 = self._offset()
        assert not offset1 != offset2
        assert offset1 == offset2

    def test_rsub(self):
        if self._offset is None or not hasattr(self, "offset2"):
            # i.e. skip for TestCommon and YQM subclasses that do not have
            # offset2 attr
            return
        assert self.d - self.offset2 == (-self.offset2).apply(self.d)

    def test_radd(self):
        if self._offset is None or not hasattr(self, "offset2"):
            # i.e. skip for TestCommon and YQM subclasses that do not have
            # offset2 attr
            return
        assert self.d + self.offset2 == self.offset2 + self.d

    def test_sub(self):
        if self._offset is None or not hasattr(self, "offset2"):
            # i.e. skip for TestCommon and YQM subclasses that do not have
            # offset2 attr
            return
        off = self.offset2
        with pytest.raises(Exception):
            off - self.d

        assert 2 * off - off == off
        assert self.d - self.offset2 == self.d + self._offset(-2)
        assert self.d - self.offset2 == self.d - (2 * off - off)

    def testMult1(self):
        if self._offset is None or not hasattr(self, "offset1"):
            # i.e. skip for TestCommon and YQM subclasses that do not have
            # offset1 attr
            return
        assert self.d + 10 * self.offset1 == self.d + self._offset(10)
        assert self.d + 5 * self.offset1 == self.d + self._offset(5)

    def testMult2(self):
        if self._offset is None:
            return
        assert self.d + (-5 * self._offset(-10)) == self.d + self._offset(50)
        assert self.d + (-3 * self._offset(-2)) == self.d + self._offset(6)

    def test_compare_str(self):
        # GH#23524
        # comparing to strings that cannot be cast to DateOffsets should
        #  not raise for __eq__ or __ne__
        if self._offset is None:
            return
        off = self._get_offset(self._offset)

        assert not off == "infer"
        assert off != "foo"
        # Note: inequalities are only implemented for Tick subclasses;
        #  tests for this are in test_ticks


class TestCommon(Base):
    # exected value created by Base._get_offset
    # are applied to 2011/01/01 09:00 (Saturday)
    # used for .apply and .rollforward
    expecteds = {'Day': Timestamp('2011-01-02 09:00:00'),
                 'DateOffset': Timestamp('2011-01-02 09:00:00'),
                 'BusinessDay': Timestamp('2011-01-03 09:00:00'),
                 'CustomBusinessDay': Timestamp('2011-01-03 09:00:00'),
                 'CustomBusinessMonthEnd': Timestamp('2011-01-31 09:00:00'),
                 'CustomBusinessMonthBegin': Timestamp('2011-01-03 09:00:00'),
                 'MonthBegin': Timestamp('2011-02-01 09:00:00'),
                 'BusinessMonthBegin': Timestamp('2011-01-03 09:00:00'),
                 'MonthEnd': Timestamp('2011-01-31 09:00:00'),
                 'SemiMonthEnd': Timestamp('2011-01-15 09:00:00'),
                 'SemiMonthBegin': Timestamp('2011-01-15 09:00:00'),
                 'BusinessMonthEnd': Timestamp('2011-01-31 09:00:00'),
                 'YearBegin': Timestamp('2012-01-01 09:00:00'),
                 'BYearBegin': Timestamp('2011-01-03 09:00:00'),
                 'YearEnd': Timestamp('2011-12-31 09:00:00'),
                 'BYearEnd': Timestamp('2011-12-30 09:00:00'),
                 'QuarterBegin': Timestamp('2011-03-01 09:00:00'),
                 'BQuarterBegin': Timestamp('2011-03-01 09:00:00'),
                 'QuarterEnd': Timestamp('2011-03-31 09:00:00'),
                 'BQuarterEnd': Timestamp('2011-03-31 09:00:00'),
                 'BusinessHour': Timestamp('2011-01-03 10:00:00'),
                 'CustomBusinessHour': Timestamp('2011-01-03 10:00:00'),
                 'WeekOfMonth': Timestamp('2011-01-08 09:00:00'),
                 'LastWeekOfMonth': Timestamp('2011-01-29 09:00:00'),
                 'FY5253Quarter': Timestamp('2011-01-25 09:00:00'),
                 'FY5253': Timestamp('2011-01-25 09:00:00'),
                 'Week': Timestamp('2011-01-08 09:00:00'),
                 'Easter': Timestamp('2011-04-24 09:00:00'),
                 'Hour': Timestamp('2011-01-01 10:00:00'),
                 'Minute': Timestamp('2011-01-01 09:01:00'),
                 'Second': Timestamp('2011-01-01 09:00:01'),
                 'Milli': Timestamp('2011-01-01 09:00:00.001000'),
                 'Micro': Timestamp('2011-01-01 09:00:00.000001'),
                 'Nano': Timestamp(np_datetime64_compat(
                                   '2011-01-01T09:00:00.000000001Z'))}

    def test_immutable(self, offset_types):
        # GH#21341 check that __setattr__ raises
        offset = self._get_offset(offset_types)
        with pytest.raises(AttributeError):
            offset.normalize = True
        with pytest.raises(AttributeError):
            offset.n = 91

    def test_return_type(self, offset_types):
        offset = self._get_offset(offset_types)

        # make sure that we are returning a Timestamp
        result = Timestamp('20080101') + offset
        assert isinstance(result, Timestamp)

        # make sure that we are returning NaT
        assert NaT + offset is NaT
        assert offset + NaT is NaT

        assert NaT - offset is NaT
        assert (-offset).apply(NaT) is NaT

    def test_offset_n(self, offset_types):
        offset = self._get_offset(offset_types)
        assert offset.n == 1

        neg_offset = offset * -1
        assert neg_offset.n == -1

        mul_offset = offset * 3
        assert mul_offset.n == 3

    def test_offset_freqstr(self, offset_types):
        offset = self._get_offset(offset_types)

        freqstr = offset.freqstr
        if freqstr not in ('<Easter>',
                           "<DateOffset: days=1>",
                           'LWOM-SAT', ):
            code = get_offset(freqstr)
            assert offset.rule_code == code

    def _check_offsetfunc_works(self, offset, funcname, dt, expected,
                                normalize=False):

        if normalize and issubclass(offset, Tick):
            # normalize=True disallowed for Tick subclasses GH#21427
            return

        offset_s = self._get_offset(offset, normalize=normalize)
        func = getattr(offset_s, funcname)

        result = func(dt)
        assert isinstance(result, Timestamp)
        assert result == expected

        result = func(Timestamp(dt))
        assert isinstance(result, Timestamp)
        assert result == expected

        # see gh-14101
        exp_warning = None
        ts = Timestamp(dt) + Nano(5)

        if (offset_s.__class__.__name__ == 'DateOffset' and
                (funcname == 'apply' or normalize) and
                ts.nanosecond > 0):
            exp_warning = UserWarning

        # test nanosecond is preserved
        with tm.assert_produces_warning(exp_warning,
                                        check_stacklevel=False):
            result = func(ts)
        assert isinstance(result, Timestamp)
        if normalize is False:
            assert result == expected + Nano(5)
        else:
            assert result == expected

        if isinstance(dt, np.datetime64):
            # test tz when input is datetime or Timestamp
            return

        for tz in self.timezones:
            expected_localize = expected.tz_localize(tz)
            tz_obj = timezones.maybe_get_tz(tz)
            dt_tz = conversion.localize_pydatetime(dt, tz_obj)

            result = func(dt_tz)
            assert isinstance(result, Timestamp)
            assert result == expected_localize

            result = func(Timestamp(dt, tz=tz))
            assert isinstance(result, Timestamp)
            assert result == expected_localize

            # see gh-14101
            exp_warning = None
            ts = Timestamp(dt, tz=tz) + Nano(5)

            if (offset_s.__class__.__name__ == 'DateOffset' and
                    (funcname == 'apply' or normalize) and
                    ts.nanosecond > 0):
                exp_warning = UserWarning

            # test nanosecond is preserved
            with tm.assert_produces_warning(exp_warning,
                                            check_stacklevel=False):
                result = func(ts)
            assert isinstance(result, Timestamp)
            if normalize is False:
                assert result == expected_localize + Nano(5)
            else:
                assert result == expected_localize

    def test_apply(self, offset_types):
        sdt = datetime(2011, 1, 1, 9, 0)
        ndt = np_datetime64_compat('2011-01-01 09:00Z')
Loading ...