Static code analysis and corrections
This commit is contained in:
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,225 @@
|
||||
from __future__ import division
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas import Interval, Timedelta, Timestamp
|
||||
import pandas.core.common as com
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def interval():
|
||||
return Interval(0, 1)
|
||||
|
||||
|
||||
class TestInterval(object):
|
||||
|
||||
def test_properties(self, interval):
|
||||
assert interval.closed == 'right'
|
||||
assert interval.left == 0
|
||||
assert interval.right == 1
|
||||
assert interval.mid == 0.5
|
||||
|
||||
def test_repr(self, interval):
|
||||
assert repr(interval) == "Interval(0, 1, closed='right')"
|
||||
assert str(interval) == "(0, 1]"
|
||||
|
||||
interval_left = Interval(0, 1, closed='left')
|
||||
assert repr(interval_left) == "Interval(0, 1, closed='left')"
|
||||
assert str(interval_left) == "[0, 1)"
|
||||
|
||||
def test_contains(self, interval):
|
||||
assert 0.5 in interval
|
||||
assert 1 in interval
|
||||
assert 0 not in interval
|
||||
|
||||
msg = "__contains__ not defined for two intervals"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval in interval
|
||||
|
||||
interval_both = Interval(0, 1, closed='both')
|
||||
assert 0 in interval_both
|
||||
assert 1 in interval_both
|
||||
|
||||
interval_neither = Interval(0, 1, closed='neither')
|
||||
assert 0 not in interval_neither
|
||||
assert 0.5 in interval_neither
|
||||
assert 1 not in interval_neither
|
||||
|
||||
def test_equal(self):
|
||||
assert Interval(0, 1) == Interval(0, 1, closed='right')
|
||||
assert Interval(0, 1) != Interval(0, 1, closed='left')
|
||||
assert Interval(0, 1) != 0
|
||||
|
||||
def test_comparison(self):
|
||||
with pytest.raises(TypeError, match='unorderable types'):
|
||||
Interval(0, 1) < 2
|
||||
|
||||
assert Interval(0, 1) < Interval(1, 2)
|
||||
assert Interval(0, 1) < Interval(0, 2)
|
||||
assert Interval(0, 1) < Interval(0.5, 1.5)
|
||||
assert Interval(0, 1) <= Interval(0, 1)
|
||||
assert Interval(0, 1) > Interval(-1, 2)
|
||||
assert Interval(0, 1) >= Interval(0, 1)
|
||||
|
||||
def test_hash(self, interval):
|
||||
# should not raise
|
||||
hash(interval)
|
||||
|
||||
@pytest.mark.parametrize('left, right, expected', [
|
||||
(0, 5, 5),
|
||||
(-2, 5.5, 7.5),
|
||||
(10, 10, 0),
|
||||
(10, np.inf, np.inf),
|
||||
(-np.inf, -5, np.inf),
|
||||
(-np.inf, np.inf, np.inf),
|
||||
(Timedelta('0 days'), Timedelta('5 days'), Timedelta('5 days')),
|
||||
(Timedelta('10 days'), Timedelta('10 days'), Timedelta('0 days')),
|
||||
(Timedelta('1H10M'), Timedelta('5H5M'), Timedelta('3H55M')),
|
||||
(Timedelta('5S'), Timedelta('1H'), Timedelta('59M55S'))])
|
||||
def test_length(self, left, right, expected):
|
||||
# GH 18789
|
||||
iv = Interval(left, right)
|
||||
result = iv.length
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('left, right, expected', [
|
||||
('2017-01-01', '2017-01-06', '5 days'),
|
||||
('2017-01-01', '2017-01-01 12:00:00', '12 hours'),
|
||||
('2017-01-01 12:00', '2017-01-01 12:00:00', '0 days'),
|
||||
('2017-01-01 12:01', '2017-01-05 17:31:00', '4 days 5 hours 30 min')])
|
||||
@pytest.mark.parametrize('tz', (None, 'UTC', 'CET', 'US/Eastern'))
|
||||
def test_length_timestamp(self, tz, left, right, expected):
|
||||
# GH 18789
|
||||
iv = Interval(Timestamp(left, tz=tz), Timestamp(right, tz=tz))
|
||||
result = iv.length
|
||||
expected = Timedelta(expected)
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('left, right', [
|
||||
('a', 'z'),
|
||||
(('a', 'b'), ('c', 'd')),
|
||||
(list('AB'), list('ab')),
|
||||
(Interval(0, 1), Interval(1, 2))])
|
||||
def test_length_errors(self, left, right):
|
||||
# GH 18789
|
||||
iv = Interval(left, right)
|
||||
msg = 'cannot compute length between .* and .*'
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
iv.length
|
||||
|
||||
def test_math_add(self, closed):
|
||||
interval = Interval(0, 1, closed=closed)
|
||||
expected = Interval(1, 2, closed=closed)
|
||||
|
||||
result = interval + 1
|
||||
assert result == expected
|
||||
|
||||
result = 1 + interval
|
||||
assert result == expected
|
||||
|
||||
result = interval
|
||||
result += 1
|
||||
assert result == expected
|
||||
|
||||
msg = r"unsupported operand type\(s\) for \+"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval + interval
|
||||
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval + 'foo'
|
||||
|
||||
def test_math_sub(self, closed):
|
||||
interval = Interval(0, 1, closed=closed)
|
||||
expected = Interval(-1, 0, closed=closed)
|
||||
|
||||
result = interval - 1
|
||||
assert result == expected
|
||||
|
||||
result = interval
|
||||
result -= 1
|
||||
assert result == expected
|
||||
|
||||
msg = r"unsupported operand type\(s\) for -"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval - interval
|
||||
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval - 'foo'
|
||||
|
||||
def test_math_mult(self, closed):
|
||||
interval = Interval(0, 1, closed=closed)
|
||||
expected = Interval(0, 2, closed=closed)
|
||||
|
||||
result = interval * 2
|
||||
assert result == expected
|
||||
|
||||
result = 2 * interval
|
||||
assert result == expected
|
||||
|
||||
result = interval
|
||||
result *= 2
|
||||
assert result == expected
|
||||
|
||||
msg = r"unsupported operand type\(s\) for \*"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval * interval
|
||||
|
||||
msg = r"can\'t multiply sequence by non-int"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval * 'foo'
|
||||
|
||||
def test_math_div(self, closed):
|
||||
interval = Interval(0, 1, closed=closed)
|
||||
expected = Interval(0, 0.5, closed=closed)
|
||||
|
||||
result = interval / 2.0
|
||||
assert result == expected
|
||||
|
||||
result = interval
|
||||
result /= 2.0
|
||||
assert result == expected
|
||||
|
||||
msg = r"unsupported operand type\(s\) for /"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval / interval
|
||||
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval / 'foo'
|
||||
|
||||
def test_math_floordiv(self, closed):
|
||||
interval = Interval(1, 2, closed=closed)
|
||||
expected = Interval(0, 1, closed=closed)
|
||||
|
||||
result = interval // 2
|
||||
assert result == expected
|
||||
|
||||
result = interval
|
||||
result //= 2
|
||||
assert result == expected
|
||||
|
||||
msg = r"unsupported operand type\(s\) for //"
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval // interval
|
||||
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval // 'foo'
|
||||
|
||||
def test_constructor_errors(self):
|
||||
msg = "invalid option for 'closed': foo"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Interval(0, 1, closed='foo')
|
||||
|
||||
msg = 'left side of interval must be <= right side'
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Interval(1, 0)
|
||||
|
||||
@pytest.mark.parametrize('tz_left, tz_right', [
|
||||
(None, 'UTC'), ('UTC', None), ('UTC', 'US/Eastern')])
|
||||
def test_constructor_errors_tz(self, tz_left, tz_right):
|
||||
# GH 18538
|
||||
left = Timestamp('2017-01-01', tz=tz_left)
|
||||
right = Timestamp('2017-01-02', tz=tz_right)
|
||||
error = TypeError if com._any_none(tz_left, tz_right) else ValueError
|
||||
with pytest.raises(error):
|
||||
Interval(left, right)
|
||||
@@ -0,0 +1,60 @@
|
||||
"""Tests for Interval-Interval operations, such as overlaps, contains, etc."""
|
||||
import pytest
|
||||
|
||||
from pandas import Interval, Timedelta, Timestamp
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
(Timedelta('0 days'), Timedelta('1 day')),
|
||||
(Timestamp('2018-01-01'), Timedelta('1 day')),
|
||||
(0, 1)], ids=lambda x: type(x[0]).__name__)
|
||||
def start_shift(request):
|
||||
"""
|
||||
Fixture for generating intervals of types from a start value and a shift
|
||||
value that can be added to start to generate an endpoint
|
||||
"""
|
||||
return request.param
|
||||
|
||||
|
||||
class TestOverlaps(object):
|
||||
|
||||
def test_overlaps_self(self, start_shift, closed):
|
||||
start, shift = start_shift
|
||||
interval = Interval(start, start + shift, closed)
|
||||
assert interval.overlaps(interval)
|
||||
|
||||
def test_overlaps_nested(self, start_shift, closed, other_closed):
|
||||
start, shift = start_shift
|
||||
interval1 = Interval(start, start + 3 * shift, other_closed)
|
||||
interval2 = Interval(start + shift, start + 2 * shift, closed)
|
||||
|
||||
# nested intervals should always overlap
|
||||
assert interval1.overlaps(interval2)
|
||||
|
||||
def test_overlaps_disjoint(self, start_shift, closed, other_closed):
|
||||
start, shift = start_shift
|
||||
interval1 = Interval(start, start + shift, other_closed)
|
||||
interval2 = Interval(start + 2 * shift, start + 3 * shift, closed)
|
||||
|
||||
# disjoint intervals should never overlap
|
||||
assert not interval1.overlaps(interval2)
|
||||
|
||||
def test_overlaps_endpoint(self, start_shift, closed, other_closed):
|
||||
start, shift = start_shift
|
||||
interval1 = Interval(start, start + shift, other_closed)
|
||||
interval2 = Interval(start + shift, start + 2 * shift, closed)
|
||||
|
||||
# overlap if shared endpoint is closed for both (overlap at a point)
|
||||
result = interval1.overlaps(interval2)
|
||||
expected = interval1.closed_right and interval2.closed_left
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('other', [
|
||||
10, True, 'foo', Timedelta('1 day'), Timestamp('2018-01-01')],
|
||||
ids=lambda x: type(x).__name__)
|
||||
def test_overlaps_invalid_type(self, other):
|
||||
interval = Interval(0, 1)
|
||||
msg = '`other` must be an Interval, got {other}'.format(
|
||||
other=type(other).__name__)
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
interval.overlaps(other)
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,747 @@
|
||||
import pytest
|
||||
|
||||
from pandas._libs.tslibs.frequencies import (
|
||||
INVALID_FREQ_ERR_MSG, _period_code_map)
|
||||
from pandas.errors import OutOfBoundsDatetime
|
||||
|
||||
from pandas import Period, offsets
|
||||
|
||||
|
||||
class TestFreqConversion(object):
|
||||
"""Test frequency conversion of date objects"""
|
||||
@pytest.mark.parametrize('freq', ['A', 'Q', 'M', 'W', 'B', 'D'])
|
||||
def test_asfreq_near_zero(self, freq):
|
||||
# GH#19643, GH#19650
|
||||
per = Period('0001-01-01', freq=freq)
|
||||
tup1 = (per.year, per.hour, per.day)
|
||||
|
||||
prev = per - 1
|
||||
assert prev.ordinal == per.ordinal - 1
|
||||
tup2 = (prev.year, prev.month, prev.day)
|
||||
assert tup2 < tup1
|
||||
|
||||
def test_asfreq_near_zero_weekly(self):
|
||||
# GH#19834
|
||||
per1 = Period('0001-01-01', 'D') + 6
|
||||
per2 = Period('0001-01-01', 'D') - 6
|
||||
week1 = per1.asfreq('W')
|
||||
week2 = per2.asfreq('W')
|
||||
assert week1 != week2
|
||||
assert week1.asfreq('D', 'E') >= per1
|
||||
assert week2.asfreq('D', 'S') <= per2
|
||||
|
||||
@pytest.mark.xfail(reason='GH#19643 period_helper asfreq functions fail '
|
||||
'to check for overflows')
|
||||
def test_to_timestamp_out_of_bounds(self):
|
||||
# GH#19643, currently gives Timestamp('1754-08-30 22:43:41.128654848')
|
||||
per = Period('0001-01-01', freq='B')
|
||||
with pytest.raises(OutOfBoundsDatetime):
|
||||
per.to_timestamp()
|
||||
|
||||
def test_asfreq_corner(self):
|
||||
val = Period(freq='A', year=2007)
|
||||
result1 = val.asfreq('5t')
|
||||
result2 = val.asfreq('t')
|
||||
expected = Period('2007-12-31 23:59', freq='t')
|
||||
assert result1.ordinal == expected.ordinal
|
||||
assert result1.freqstr == '5T'
|
||||
assert result2.ordinal == expected.ordinal
|
||||
assert result2.freqstr == 'T'
|
||||
|
||||
def test_conv_annual(self):
|
||||
# frequency conversion tests: from Annual Frequency
|
||||
|
||||
ival_A = Period(freq='A', year=2007)
|
||||
|
||||
ival_AJAN = Period(freq="A-JAN", year=2007)
|
||||
ival_AJUN = Period(freq="A-JUN", year=2007)
|
||||
ival_ANOV = Period(freq="A-NOV", year=2007)
|
||||
|
||||
ival_A_to_Q_start = Period(freq='Q', year=2007, quarter=1)
|
||||
ival_A_to_Q_end = Period(freq='Q', year=2007, quarter=4)
|
||||
ival_A_to_M_start = Period(freq='M', year=2007, month=1)
|
||||
ival_A_to_M_end = Period(freq='M', year=2007, month=12)
|
||||
ival_A_to_W_start = Period(freq='W', year=2007, month=1, day=1)
|
||||
ival_A_to_W_end = Period(freq='W', year=2007, month=12, day=31)
|
||||
ival_A_to_B_start = Period(freq='B', year=2007, month=1, day=1)
|
||||
ival_A_to_B_end = Period(freq='B', year=2007, month=12, day=31)
|
||||
ival_A_to_D_start = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_A_to_D_end = Period(freq='D', year=2007, month=12, day=31)
|
||||
ival_A_to_H_start = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
ival_A_to_H_end = Period(freq='H', year=2007, month=12, day=31,
|
||||
hour=23)
|
||||
ival_A_to_T_start = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=0, minute=0)
|
||||
ival_A_to_T_end = Period(freq='Min', year=2007, month=12, day=31,
|
||||
hour=23, minute=59)
|
||||
ival_A_to_S_start = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=0)
|
||||
ival_A_to_S_end = Period(freq='S', year=2007, month=12, day=31,
|
||||
hour=23, minute=59, second=59)
|
||||
|
||||
ival_AJAN_to_D_end = Period(freq='D', year=2007, month=1, day=31)
|
||||
ival_AJAN_to_D_start = Period(freq='D', year=2006, month=2, day=1)
|
||||
ival_AJUN_to_D_end = Period(freq='D', year=2007, month=6, day=30)
|
||||
ival_AJUN_to_D_start = Period(freq='D', year=2006, month=7, day=1)
|
||||
ival_ANOV_to_D_end = Period(freq='D', year=2007, month=11, day=30)
|
||||
ival_ANOV_to_D_start = Period(freq='D', year=2006, month=12, day=1)
|
||||
|
||||
assert ival_A.asfreq('Q', 'S') == ival_A_to_Q_start
|
||||
assert ival_A.asfreq('Q', 'e') == ival_A_to_Q_end
|
||||
assert ival_A.asfreq('M', 's') == ival_A_to_M_start
|
||||
assert ival_A.asfreq('M', 'E') == ival_A_to_M_end
|
||||
assert ival_A.asfreq('W', 'S') == ival_A_to_W_start
|
||||
assert ival_A.asfreq('W', 'E') == ival_A_to_W_end
|
||||
assert ival_A.asfreq('B', 'S') == ival_A_to_B_start
|
||||
assert ival_A.asfreq('B', 'E') == ival_A_to_B_end
|
||||
assert ival_A.asfreq('D', 'S') == ival_A_to_D_start
|
||||
assert ival_A.asfreq('D', 'E') == ival_A_to_D_end
|
||||
assert ival_A.asfreq('H', 'S') == ival_A_to_H_start
|
||||
assert ival_A.asfreq('H', 'E') == ival_A_to_H_end
|
||||
assert ival_A.asfreq('min', 'S') == ival_A_to_T_start
|
||||
assert ival_A.asfreq('min', 'E') == ival_A_to_T_end
|
||||
assert ival_A.asfreq('T', 'S') == ival_A_to_T_start
|
||||
assert ival_A.asfreq('T', 'E') == ival_A_to_T_end
|
||||
assert ival_A.asfreq('S', 'S') == ival_A_to_S_start
|
||||
assert ival_A.asfreq('S', 'E') == ival_A_to_S_end
|
||||
|
||||
assert ival_AJAN.asfreq('D', 'S') == ival_AJAN_to_D_start
|
||||
assert ival_AJAN.asfreq('D', 'E') == ival_AJAN_to_D_end
|
||||
|
||||
assert ival_AJUN.asfreq('D', 'S') == ival_AJUN_to_D_start
|
||||
assert ival_AJUN.asfreq('D', 'E') == ival_AJUN_to_D_end
|
||||
|
||||
assert ival_ANOV.asfreq('D', 'S') == ival_ANOV_to_D_start
|
||||
assert ival_ANOV.asfreq('D', 'E') == ival_ANOV_to_D_end
|
||||
|
||||
assert ival_A.asfreq('A') == ival_A
|
||||
|
||||
def test_conv_quarterly(self):
|
||||
# frequency conversion tests: from Quarterly Frequency
|
||||
|
||||
ival_Q = Period(freq='Q', year=2007, quarter=1)
|
||||
ival_Q_end_of_year = Period(freq='Q', year=2007, quarter=4)
|
||||
|
||||
ival_QEJAN = Period(freq="Q-JAN", year=2007, quarter=1)
|
||||
ival_QEJUN = Period(freq="Q-JUN", year=2007, quarter=1)
|
||||
|
||||
ival_Q_to_A = Period(freq='A', year=2007)
|
||||
ival_Q_to_M_start = Period(freq='M', year=2007, month=1)
|
||||
ival_Q_to_M_end = Period(freq='M', year=2007, month=3)
|
||||
ival_Q_to_W_start = Period(freq='W', year=2007, month=1, day=1)
|
||||
ival_Q_to_W_end = Period(freq='W', year=2007, month=3, day=31)
|
||||
ival_Q_to_B_start = Period(freq='B', year=2007, month=1, day=1)
|
||||
ival_Q_to_B_end = Period(freq='B', year=2007, month=3, day=30)
|
||||
ival_Q_to_D_start = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_Q_to_D_end = Period(freq='D', year=2007, month=3, day=31)
|
||||
ival_Q_to_H_start = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
ival_Q_to_H_end = Period(freq='H', year=2007, month=3, day=31, hour=23)
|
||||
ival_Q_to_T_start = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=0, minute=0)
|
||||
ival_Q_to_T_end = Period(freq='Min', year=2007, month=3, day=31,
|
||||
hour=23, minute=59)
|
||||
ival_Q_to_S_start = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=0)
|
||||
ival_Q_to_S_end = Period(freq='S', year=2007, month=3, day=31, hour=23,
|
||||
minute=59, second=59)
|
||||
|
||||
ival_QEJAN_to_D_start = Period(freq='D', year=2006, month=2, day=1)
|
||||
ival_QEJAN_to_D_end = Period(freq='D', year=2006, month=4, day=30)
|
||||
|
||||
ival_QEJUN_to_D_start = Period(freq='D', year=2006, month=7, day=1)
|
||||
ival_QEJUN_to_D_end = Period(freq='D', year=2006, month=9, day=30)
|
||||
|
||||
assert ival_Q.asfreq('A') == ival_Q_to_A
|
||||
assert ival_Q_end_of_year.asfreq('A') == ival_Q_to_A
|
||||
|
||||
assert ival_Q.asfreq('M', 'S') == ival_Q_to_M_start
|
||||
assert ival_Q.asfreq('M', 'E') == ival_Q_to_M_end
|
||||
assert ival_Q.asfreq('W', 'S') == ival_Q_to_W_start
|
||||
assert ival_Q.asfreq('W', 'E') == ival_Q_to_W_end
|
||||
assert ival_Q.asfreq('B', 'S') == ival_Q_to_B_start
|
||||
assert ival_Q.asfreq('B', 'E') == ival_Q_to_B_end
|
||||
assert ival_Q.asfreq('D', 'S') == ival_Q_to_D_start
|
||||
assert ival_Q.asfreq('D', 'E') == ival_Q_to_D_end
|
||||
assert ival_Q.asfreq('H', 'S') == ival_Q_to_H_start
|
||||
assert ival_Q.asfreq('H', 'E') == ival_Q_to_H_end
|
||||
assert ival_Q.asfreq('Min', 'S') == ival_Q_to_T_start
|
||||
assert ival_Q.asfreq('Min', 'E') == ival_Q_to_T_end
|
||||
assert ival_Q.asfreq('S', 'S') == ival_Q_to_S_start
|
||||
assert ival_Q.asfreq('S', 'E') == ival_Q_to_S_end
|
||||
|
||||
assert ival_QEJAN.asfreq('D', 'S') == ival_QEJAN_to_D_start
|
||||
assert ival_QEJAN.asfreq('D', 'E') == ival_QEJAN_to_D_end
|
||||
assert ival_QEJUN.asfreq('D', 'S') == ival_QEJUN_to_D_start
|
||||
assert ival_QEJUN.asfreq('D', 'E') == ival_QEJUN_to_D_end
|
||||
|
||||
assert ival_Q.asfreq('Q') == ival_Q
|
||||
|
||||
def test_conv_monthly(self):
|
||||
# frequency conversion tests: from Monthly Frequency
|
||||
|
||||
ival_M = Period(freq='M', year=2007, month=1)
|
||||
ival_M_end_of_year = Period(freq='M', year=2007, month=12)
|
||||
ival_M_end_of_quarter = Period(freq='M', year=2007, month=3)
|
||||
ival_M_to_A = Period(freq='A', year=2007)
|
||||
ival_M_to_Q = Period(freq='Q', year=2007, quarter=1)
|
||||
ival_M_to_W_start = Period(freq='W', year=2007, month=1, day=1)
|
||||
ival_M_to_W_end = Period(freq='W', year=2007, month=1, day=31)
|
||||
ival_M_to_B_start = Period(freq='B', year=2007, month=1, day=1)
|
||||
ival_M_to_B_end = Period(freq='B', year=2007, month=1, day=31)
|
||||
ival_M_to_D_start = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_M_to_D_end = Period(freq='D', year=2007, month=1, day=31)
|
||||
ival_M_to_H_start = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
ival_M_to_H_end = Period(freq='H', year=2007, month=1, day=31, hour=23)
|
||||
ival_M_to_T_start = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=0, minute=0)
|
||||
ival_M_to_T_end = Period(freq='Min', year=2007, month=1, day=31,
|
||||
hour=23, minute=59)
|
||||
ival_M_to_S_start = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=0)
|
||||
ival_M_to_S_end = Period(freq='S', year=2007, month=1, day=31, hour=23,
|
||||
minute=59, second=59)
|
||||
|
||||
assert ival_M.asfreq('A') == ival_M_to_A
|
||||
assert ival_M_end_of_year.asfreq('A') == ival_M_to_A
|
||||
assert ival_M.asfreq('Q') == ival_M_to_Q
|
||||
assert ival_M_end_of_quarter.asfreq('Q') == ival_M_to_Q
|
||||
|
||||
assert ival_M.asfreq('W', 'S') == ival_M_to_W_start
|
||||
assert ival_M.asfreq('W', 'E') == ival_M_to_W_end
|
||||
assert ival_M.asfreq('B', 'S') == ival_M_to_B_start
|
||||
assert ival_M.asfreq('B', 'E') == ival_M_to_B_end
|
||||
assert ival_M.asfreq('D', 'S') == ival_M_to_D_start
|
||||
assert ival_M.asfreq('D', 'E') == ival_M_to_D_end
|
||||
assert ival_M.asfreq('H', 'S') == ival_M_to_H_start
|
||||
assert ival_M.asfreq('H', 'E') == ival_M_to_H_end
|
||||
assert ival_M.asfreq('Min', 'S') == ival_M_to_T_start
|
||||
assert ival_M.asfreq('Min', 'E') == ival_M_to_T_end
|
||||
assert ival_M.asfreq('S', 'S') == ival_M_to_S_start
|
||||
assert ival_M.asfreq('S', 'E') == ival_M_to_S_end
|
||||
|
||||
assert ival_M.asfreq('M') == ival_M
|
||||
|
||||
def test_conv_weekly(self):
|
||||
# frequency conversion tests: from Weekly Frequency
|
||||
ival_W = Period(freq='W', year=2007, month=1, day=1)
|
||||
|
||||
ival_WSUN = Period(freq='W', year=2007, month=1, day=7)
|
||||
ival_WSAT = Period(freq='W-SAT', year=2007, month=1, day=6)
|
||||
ival_WFRI = Period(freq='W-FRI', year=2007, month=1, day=5)
|
||||
ival_WTHU = Period(freq='W-THU', year=2007, month=1, day=4)
|
||||
ival_WWED = Period(freq='W-WED', year=2007, month=1, day=3)
|
||||
ival_WTUE = Period(freq='W-TUE', year=2007, month=1, day=2)
|
||||
ival_WMON = Period(freq='W-MON', year=2007, month=1, day=1)
|
||||
|
||||
ival_WSUN_to_D_start = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_WSUN_to_D_end = Period(freq='D', year=2007, month=1, day=7)
|
||||
ival_WSAT_to_D_start = Period(freq='D', year=2006, month=12, day=31)
|
||||
ival_WSAT_to_D_end = Period(freq='D', year=2007, month=1, day=6)
|
||||
ival_WFRI_to_D_start = Period(freq='D', year=2006, month=12, day=30)
|
||||
ival_WFRI_to_D_end = Period(freq='D', year=2007, month=1, day=5)
|
||||
ival_WTHU_to_D_start = Period(freq='D', year=2006, month=12, day=29)
|
||||
ival_WTHU_to_D_end = Period(freq='D', year=2007, month=1, day=4)
|
||||
ival_WWED_to_D_start = Period(freq='D', year=2006, month=12, day=28)
|
||||
ival_WWED_to_D_end = Period(freq='D', year=2007, month=1, day=3)
|
||||
ival_WTUE_to_D_start = Period(freq='D', year=2006, month=12, day=27)
|
||||
ival_WTUE_to_D_end = Period(freq='D', year=2007, month=1, day=2)
|
||||
ival_WMON_to_D_start = Period(freq='D', year=2006, month=12, day=26)
|
||||
ival_WMON_to_D_end = Period(freq='D', year=2007, month=1, day=1)
|
||||
|
||||
ival_W_end_of_year = Period(freq='W', year=2007, month=12, day=31)
|
||||
ival_W_end_of_quarter = Period(freq='W', year=2007, month=3, day=31)
|
||||
ival_W_end_of_month = Period(freq='W', year=2007, month=1, day=31)
|
||||
ival_W_to_A = Period(freq='A', year=2007)
|
||||
ival_W_to_Q = Period(freq='Q', year=2007, quarter=1)
|
||||
ival_W_to_M = Period(freq='M', year=2007, month=1)
|
||||
|
||||
if Period(freq='D', year=2007, month=12, day=31).weekday == 6:
|
||||
ival_W_to_A_end_of_year = Period(freq='A', year=2007)
|
||||
else:
|
||||
ival_W_to_A_end_of_year = Period(freq='A', year=2008)
|
||||
|
||||
if Period(freq='D', year=2007, month=3, day=31).weekday == 6:
|
||||
ival_W_to_Q_end_of_quarter = Period(freq='Q', year=2007, quarter=1)
|
||||
else:
|
||||
ival_W_to_Q_end_of_quarter = Period(freq='Q', year=2007, quarter=2)
|
||||
|
||||
if Period(freq='D', year=2007, month=1, day=31).weekday == 6:
|
||||
ival_W_to_M_end_of_month = Period(freq='M', year=2007, month=1)
|
||||
else:
|
||||
ival_W_to_M_end_of_month = Period(freq='M', year=2007, month=2)
|
||||
|
||||
ival_W_to_B_start = Period(freq='B', year=2007, month=1, day=1)
|
||||
ival_W_to_B_end = Period(freq='B', year=2007, month=1, day=5)
|
||||
ival_W_to_D_start = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_W_to_D_end = Period(freq='D', year=2007, month=1, day=7)
|
||||
ival_W_to_H_start = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
ival_W_to_H_end = Period(freq='H', year=2007, month=1, day=7, hour=23)
|
||||
ival_W_to_T_start = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=0, minute=0)
|
||||
ival_W_to_T_end = Period(freq='Min', year=2007, month=1, day=7,
|
||||
hour=23, minute=59)
|
||||
ival_W_to_S_start = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=0)
|
||||
ival_W_to_S_end = Period(freq='S', year=2007, month=1, day=7, hour=23,
|
||||
minute=59, second=59)
|
||||
|
||||
assert ival_W.asfreq('A') == ival_W_to_A
|
||||
assert ival_W_end_of_year.asfreq('A') == ival_W_to_A_end_of_year
|
||||
|
||||
assert ival_W.asfreq('Q') == ival_W_to_Q
|
||||
assert ival_W_end_of_quarter.asfreq('Q') == ival_W_to_Q_end_of_quarter
|
||||
|
||||
assert ival_W.asfreq('M') == ival_W_to_M
|
||||
assert ival_W_end_of_month.asfreq('M') == ival_W_to_M_end_of_month
|
||||
|
||||
assert ival_W.asfreq('B', 'S') == ival_W_to_B_start
|
||||
assert ival_W.asfreq('B', 'E') == ival_W_to_B_end
|
||||
|
||||
assert ival_W.asfreq('D', 'S') == ival_W_to_D_start
|
||||
assert ival_W.asfreq('D', 'E') == ival_W_to_D_end
|
||||
|
||||
assert ival_WSUN.asfreq('D', 'S') == ival_WSUN_to_D_start
|
||||
assert ival_WSUN.asfreq('D', 'E') == ival_WSUN_to_D_end
|
||||
assert ival_WSAT.asfreq('D', 'S') == ival_WSAT_to_D_start
|
||||
assert ival_WSAT.asfreq('D', 'E') == ival_WSAT_to_D_end
|
||||
assert ival_WFRI.asfreq('D', 'S') == ival_WFRI_to_D_start
|
||||
assert ival_WFRI.asfreq('D', 'E') == ival_WFRI_to_D_end
|
||||
assert ival_WTHU.asfreq('D', 'S') == ival_WTHU_to_D_start
|
||||
assert ival_WTHU.asfreq('D', 'E') == ival_WTHU_to_D_end
|
||||
assert ival_WWED.asfreq('D', 'S') == ival_WWED_to_D_start
|
||||
assert ival_WWED.asfreq('D', 'E') == ival_WWED_to_D_end
|
||||
assert ival_WTUE.asfreq('D', 'S') == ival_WTUE_to_D_start
|
||||
assert ival_WTUE.asfreq('D', 'E') == ival_WTUE_to_D_end
|
||||
assert ival_WMON.asfreq('D', 'S') == ival_WMON_to_D_start
|
||||
assert ival_WMON.asfreq('D', 'E') == ival_WMON_to_D_end
|
||||
|
||||
assert ival_W.asfreq('H', 'S') == ival_W_to_H_start
|
||||
assert ival_W.asfreq('H', 'E') == ival_W_to_H_end
|
||||
assert ival_W.asfreq('Min', 'S') == ival_W_to_T_start
|
||||
assert ival_W.asfreq('Min', 'E') == ival_W_to_T_end
|
||||
assert ival_W.asfreq('S', 'S') == ival_W_to_S_start
|
||||
assert ival_W.asfreq('S', 'E') == ival_W_to_S_end
|
||||
|
||||
assert ival_W.asfreq('W') == ival_W
|
||||
|
||||
msg = INVALID_FREQ_ERR_MSG
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
ival_W.asfreq('WK')
|
||||
|
||||
def test_conv_weekly_legacy(self):
|
||||
# frequency conversion tests: from Weekly Frequency
|
||||
msg = INVALID_FREQ_ERR_MSG
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Period(freq='WK', year=2007, month=1, day=1)
|
||||
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Period(freq='WK-SAT', year=2007, month=1, day=6)
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Period(freq='WK-FRI', year=2007, month=1, day=5)
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Period(freq='WK-THU', year=2007, month=1, day=4)
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Period(freq='WK-WED', year=2007, month=1, day=3)
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Period(freq='WK-TUE', year=2007, month=1, day=2)
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Period(freq='WK-MON', year=2007, month=1, day=1)
|
||||
|
||||
def test_conv_business(self):
|
||||
# frequency conversion tests: from Business Frequency"
|
||||
|
||||
ival_B = Period(freq='B', year=2007, month=1, day=1)
|
||||
ival_B_end_of_year = Period(freq='B', year=2007, month=12, day=31)
|
||||
ival_B_end_of_quarter = Period(freq='B', year=2007, month=3, day=30)
|
||||
ival_B_end_of_month = Period(freq='B', year=2007, month=1, day=31)
|
||||
ival_B_end_of_week = Period(freq='B', year=2007, month=1, day=5)
|
||||
|
||||
ival_B_to_A = Period(freq='A', year=2007)
|
||||
ival_B_to_Q = Period(freq='Q', year=2007, quarter=1)
|
||||
ival_B_to_M = Period(freq='M', year=2007, month=1)
|
||||
ival_B_to_W = Period(freq='W', year=2007, month=1, day=7)
|
||||
ival_B_to_D = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_B_to_H_start = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
ival_B_to_H_end = Period(freq='H', year=2007, month=1, day=1, hour=23)
|
||||
ival_B_to_T_start = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=0, minute=0)
|
||||
ival_B_to_T_end = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=23, minute=59)
|
||||
ival_B_to_S_start = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=0)
|
||||
ival_B_to_S_end = Period(freq='S', year=2007, month=1, day=1, hour=23,
|
||||
minute=59, second=59)
|
||||
|
||||
assert ival_B.asfreq('A') == ival_B_to_A
|
||||
assert ival_B_end_of_year.asfreq('A') == ival_B_to_A
|
||||
assert ival_B.asfreq('Q') == ival_B_to_Q
|
||||
assert ival_B_end_of_quarter.asfreq('Q') == ival_B_to_Q
|
||||
assert ival_B.asfreq('M') == ival_B_to_M
|
||||
assert ival_B_end_of_month.asfreq('M') == ival_B_to_M
|
||||
assert ival_B.asfreq('W') == ival_B_to_W
|
||||
assert ival_B_end_of_week.asfreq('W') == ival_B_to_W
|
||||
|
||||
assert ival_B.asfreq('D') == ival_B_to_D
|
||||
|
||||
assert ival_B.asfreq('H', 'S') == ival_B_to_H_start
|
||||
assert ival_B.asfreq('H', 'E') == ival_B_to_H_end
|
||||
assert ival_B.asfreq('Min', 'S') == ival_B_to_T_start
|
||||
assert ival_B.asfreq('Min', 'E') == ival_B_to_T_end
|
||||
assert ival_B.asfreq('S', 'S') == ival_B_to_S_start
|
||||
assert ival_B.asfreq('S', 'E') == ival_B_to_S_end
|
||||
|
||||
assert ival_B.asfreq('B') == ival_B
|
||||
|
||||
def test_conv_daily(self):
|
||||
# frequency conversion tests: from Business Frequency"
|
||||
|
||||
ival_D = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_D_end_of_year = Period(freq='D', year=2007, month=12, day=31)
|
||||
ival_D_end_of_quarter = Period(freq='D', year=2007, month=3, day=31)
|
||||
ival_D_end_of_month = Period(freq='D', year=2007, month=1, day=31)
|
||||
ival_D_end_of_week = Period(freq='D', year=2007, month=1, day=7)
|
||||
|
||||
ival_D_friday = Period(freq='D', year=2007, month=1, day=5)
|
||||
ival_D_saturday = Period(freq='D', year=2007, month=1, day=6)
|
||||
ival_D_sunday = Period(freq='D', year=2007, month=1, day=7)
|
||||
|
||||
# TODO: unused?
|
||||
# ival_D_monday = Period(freq='D', year=2007, month=1, day=8)
|
||||
|
||||
ival_B_friday = Period(freq='B', year=2007, month=1, day=5)
|
||||
ival_B_monday = Period(freq='B', year=2007, month=1, day=8)
|
||||
|
||||
ival_D_to_A = Period(freq='A', year=2007)
|
||||
|
||||
ival_Deoq_to_AJAN = Period(freq='A-JAN', year=2008)
|
||||
ival_Deoq_to_AJUN = Period(freq='A-JUN', year=2007)
|
||||
ival_Deoq_to_ADEC = Period(freq='A-DEC', year=2007)
|
||||
|
||||
ival_D_to_QEJAN = Period(freq="Q-JAN", year=2007, quarter=4)
|
||||
ival_D_to_QEJUN = Period(freq="Q-JUN", year=2007, quarter=3)
|
||||
ival_D_to_QEDEC = Period(freq="Q-DEC", year=2007, quarter=1)
|
||||
|
||||
ival_D_to_M = Period(freq='M', year=2007, month=1)
|
||||
ival_D_to_W = Period(freq='W', year=2007, month=1, day=7)
|
||||
|
||||
ival_D_to_H_start = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
ival_D_to_H_end = Period(freq='H', year=2007, month=1, day=1, hour=23)
|
||||
ival_D_to_T_start = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=0, minute=0)
|
||||
ival_D_to_T_end = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=23, minute=59)
|
||||
ival_D_to_S_start = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=0)
|
||||
ival_D_to_S_end = Period(freq='S', year=2007, month=1, day=1, hour=23,
|
||||
minute=59, second=59)
|
||||
|
||||
assert ival_D.asfreq('A') == ival_D_to_A
|
||||
|
||||
assert ival_D_end_of_quarter.asfreq('A-JAN') == ival_Deoq_to_AJAN
|
||||
assert ival_D_end_of_quarter.asfreq('A-JUN') == ival_Deoq_to_AJUN
|
||||
assert ival_D_end_of_quarter.asfreq('A-DEC') == ival_Deoq_to_ADEC
|
||||
|
||||
assert ival_D_end_of_year.asfreq('A') == ival_D_to_A
|
||||
assert ival_D_end_of_quarter.asfreq('Q') == ival_D_to_QEDEC
|
||||
assert ival_D.asfreq("Q-JAN") == ival_D_to_QEJAN
|
||||
assert ival_D.asfreq("Q-JUN") == ival_D_to_QEJUN
|
||||
assert ival_D.asfreq("Q-DEC") == ival_D_to_QEDEC
|
||||
assert ival_D.asfreq('M') == ival_D_to_M
|
||||
assert ival_D_end_of_month.asfreq('M') == ival_D_to_M
|
||||
assert ival_D.asfreq('W') == ival_D_to_W
|
||||
assert ival_D_end_of_week.asfreq('W') == ival_D_to_W
|
||||
|
||||
assert ival_D_friday.asfreq('B') == ival_B_friday
|
||||
assert ival_D_saturday.asfreq('B', 'S') == ival_B_friday
|
||||
assert ival_D_saturday.asfreq('B', 'E') == ival_B_monday
|
||||
assert ival_D_sunday.asfreq('B', 'S') == ival_B_friday
|
||||
assert ival_D_sunday.asfreq('B', 'E') == ival_B_monday
|
||||
|
||||
assert ival_D.asfreq('H', 'S') == ival_D_to_H_start
|
||||
assert ival_D.asfreq('H', 'E') == ival_D_to_H_end
|
||||
assert ival_D.asfreq('Min', 'S') == ival_D_to_T_start
|
||||
assert ival_D.asfreq('Min', 'E') == ival_D_to_T_end
|
||||
assert ival_D.asfreq('S', 'S') == ival_D_to_S_start
|
||||
assert ival_D.asfreq('S', 'E') == ival_D_to_S_end
|
||||
|
||||
assert ival_D.asfreq('D') == ival_D
|
||||
|
||||
def test_conv_hourly(self):
|
||||
# frequency conversion tests: from Hourly Frequency"
|
||||
|
||||
ival_H = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
ival_H_end_of_year = Period(freq='H', year=2007, month=12, day=31,
|
||||
hour=23)
|
||||
ival_H_end_of_quarter = Period(freq='H', year=2007, month=3, day=31,
|
||||
hour=23)
|
||||
ival_H_end_of_month = Period(freq='H', year=2007, month=1, day=31,
|
||||
hour=23)
|
||||
ival_H_end_of_week = Period(freq='H', year=2007, month=1, day=7,
|
||||
hour=23)
|
||||
ival_H_end_of_day = Period(freq='H', year=2007, month=1, day=1,
|
||||
hour=23)
|
||||
ival_H_end_of_bus = Period(freq='H', year=2007, month=1, day=1,
|
||||
hour=23)
|
||||
|
||||
ival_H_to_A = Period(freq='A', year=2007)
|
||||
ival_H_to_Q = Period(freq='Q', year=2007, quarter=1)
|
||||
ival_H_to_M = Period(freq='M', year=2007, month=1)
|
||||
ival_H_to_W = Period(freq='W', year=2007, month=1, day=7)
|
||||
ival_H_to_D = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_H_to_B = Period(freq='B', year=2007, month=1, day=1)
|
||||
|
||||
ival_H_to_T_start = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=0, minute=0)
|
||||
ival_H_to_T_end = Period(freq='Min', year=2007, month=1, day=1, hour=0,
|
||||
minute=59)
|
||||
ival_H_to_S_start = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=0)
|
||||
ival_H_to_S_end = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=59, second=59)
|
||||
|
||||
assert ival_H.asfreq('A') == ival_H_to_A
|
||||
assert ival_H_end_of_year.asfreq('A') == ival_H_to_A
|
||||
assert ival_H.asfreq('Q') == ival_H_to_Q
|
||||
assert ival_H_end_of_quarter.asfreq('Q') == ival_H_to_Q
|
||||
assert ival_H.asfreq('M') == ival_H_to_M
|
||||
assert ival_H_end_of_month.asfreq('M') == ival_H_to_M
|
||||
assert ival_H.asfreq('W') == ival_H_to_W
|
||||
assert ival_H_end_of_week.asfreq('W') == ival_H_to_W
|
||||
assert ival_H.asfreq('D') == ival_H_to_D
|
||||
assert ival_H_end_of_day.asfreq('D') == ival_H_to_D
|
||||
assert ival_H.asfreq('B') == ival_H_to_B
|
||||
assert ival_H_end_of_bus.asfreq('B') == ival_H_to_B
|
||||
|
||||
assert ival_H.asfreq('Min', 'S') == ival_H_to_T_start
|
||||
assert ival_H.asfreq('Min', 'E') == ival_H_to_T_end
|
||||
assert ival_H.asfreq('S', 'S') == ival_H_to_S_start
|
||||
assert ival_H.asfreq('S', 'E') == ival_H_to_S_end
|
||||
|
||||
assert ival_H.asfreq('H') == ival_H
|
||||
|
||||
def test_conv_minutely(self):
|
||||
# frequency conversion tests: from Minutely Frequency"
|
||||
|
||||
ival_T = Period(freq='Min', year=2007, month=1, day=1, hour=0,
|
||||
minute=0)
|
||||
ival_T_end_of_year = Period(freq='Min', year=2007, month=12, day=31,
|
||||
hour=23, minute=59)
|
||||
ival_T_end_of_quarter = Period(freq='Min', year=2007, month=3, day=31,
|
||||
hour=23, minute=59)
|
||||
ival_T_end_of_month = Period(freq='Min', year=2007, month=1, day=31,
|
||||
hour=23, minute=59)
|
||||
ival_T_end_of_week = Period(freq='Min', year=2007, month=1, day=7,
|
||||
hour=23, minute=59)
|
||||
ival_T_end_of_day = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=23, minute=59)
|
||||
ival_T_end_of_bus = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=23, minute=59)
|
||||
ival_T_end_of_hour = Period(freq='Min', year=2007, month=1, day=1,
|
||||
hour=0, minute=59)
|
||||
|
||||
ival_T_to_A = Period(freq='A', year=2007)
|
||||
ival_T_to_Q = Period(freq='Q', year=2007, quarter=1)
|
||||
ival_T_to_M = Period(freq='M', year=2007, month=1)
|
||||
ival_T_to_W = Period(freq='W', year=2007, month=1, day=7)
|
||||
ival_T_to_D = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_T_to_B = Period(freq='B', year=2007, month=1, day=1)
|
||||
ival_T_to_H = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
|
||||
ival_T_to_S_start = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=0)
|
||||
ival_T_to_S_end = Period(freq='S', year=2007, month=1, day=1, hour=0,
|
||||
minute=0, second=59)
|
||||
|
||||
assert ival_T.asfreq('A') == ival_T_to_A
|
||||
assert ival_T_end_of_year.asfreq('A') == ival_T_to_A
|
||||
assert ival_T.asfreq('Q') == ival_T_to_Q
|
||||
assert ival_T_end_of_quarter.asfreq('Q') == ival_T_to_Q
|
||||
assert ival_T.asfreq('M') == ival_T_to_M
|
||||
assert ival_T_end_of_month.asfreq('M') == ival_T_to_M
|
||||
assert ival_T.asfreq('W') == ival_T_to_W
|
||||
assert ival_T_end_of_week.asfreq('W') == ival_T_to_W
|
||||
assert ival_T.asfreq('D') == ival_T_to_D
|
||||
assert ival_T_end_of_day.asfreq('D') == ival_T_to_D
|
||||
assert ival_T.asfreq('B') == ival_T_to_B
|
||||
assert ival_T_end_of_bus.asfreq('B') == ival_T_to_B
|
||||
assert ival_T.asfreq('H') == ival_T_to_H
|
||||
assert ival_T_end_of_hour.asfreq('H') == ival_T_to_H
|
||||
|
||||
assert ival_T.asfreq('S', 'S') == ival_T_to_S_start
|
||||
assert ival_T.asfreq('S', 'E') == ival_T_to_S_end
|
||||
|
||||
assert ival_T.asfreq('Min') == ival_T
|
||||
|
||||
def test_conv_secondly(self):
|
||||
# frequency conversion tests: from Secondly Frequency"
|
||||
|
||||
ival_S = Period(freq='S', year=2007, month=1, day=1, hour=0, minute=0,
|
||||
second=0)
|
||||
ival_S_end_of_year = Period(freq='S', year=2007, month=12, day=31,
|
||||
hour=23, minute=59, second=59)
|
||||
ival_S_end_of_quarter = Period(freq='S', year=2007, month=3, day=31,
|
||||
hour=23, minute=59, second=59)
|
||||
ival_S_end_of_month = Period(freq='S', year=2007, month=1, day=31,
|
||||
hour=23, minute=59, second=59)
|
||||
ival_S_end_of_week = Period(freq='S', year=2007, month=1, day=7,
|
||||
hour=23, minute=59, second=59)
|
||||
ival_S_end_of_day = Period(freq='S', year=2007, month=1, day=1,
|
||||
hour=23, minute=59, second=59)
|
||||
ival_S_end_of_bus = Period(freq='S', year=2007, month=1, day=1,
|
||||
hour=23, minute=59, second=59)
|
||||
ival_S_end_of_hour = Period(freq='S', year=2007, month=1, day=1,
|
||||
hour=0, minute=59, second=59)
|
||||
ival_S_end_of_minute = Period(freq='S', year=2007, month=1, day=1,
|
||||
hour=0, minute=0, second=59)
|
||||
|
||||
ival_S_to_A = Period(freq='A', year=2007)
|
||||
ival_S_to_Q = Period(freq='Q', year=2007, quarter=1)
|
||||
ival_S_to_M = Period(freq='M', year=2007, month=1)
|
||||
ival_S_to_W = Period(freq='W', year=2007, month=1, day=7)
|
||||
ival_S_to_D = Period(freq='D', year=2007, month=1, day=1)
|
||||
ival_S_to_B = Period(freq='B', year=2007, month=1, day=1)
|
||||
ival_S_to_H = Period(freq='H', year=2007, month=1, day=1, hour=0)
|
||||
ival_S_to_T = Period(freq='Min', year=2007, month=1, day=1, hour=0,
|
||||
minute=0)
|
||||
|
||||
assert ival_S.asfreq('A') == ival_S_to_A
|
||||
assert ival_S_end_of_year.asfreq('A') == ival_S_to_A
|
||||
assert ival_S.asfreq('Q') == ival_S_to_Q
|
||||
assert ival_S_end_of_quarter.asfreq('Q') == ival_S_to_Q
|
||||
assert ival_S.asfreq('M') == ival_S_to_M
|
||||
assert ival_S_end_of_month.asfreq('M') == ival_S_to_M
|
||||
assert ival_S.asfreq('W') == ival_S_to_W
|
||||
assert ival_S_end_of_week.asfreq('W') == ival_S_to_W
|
||||
assert ival_S.asfreq('D') == ival_S_to_D
|
||||
assert ival_S_end_of_day.asfreq('D') == ival_S_to_D
|
||||
assert ival_S.asfreq('B') == ival_S_to_B
|
||||
assert ival_S_end_of_bus.asfreq('B') == ival_S_to_B
|
||||
assert ival_S.asfreq('H') == ival_S_to_H
|
||||
assert ival_S_end_of_hour.asfreq('H') == ival_S_to_H
|
||||
assert ival_S.asfreq('Min') == ival_S_to_T
|
||||
assert ival_S_end_of_minute.asfreq('Min') == ival_S_to_T
|
||||
|
||||
assert ival_S.asfreq('S') == ival_S
|
||||
|
||||
def test_asfreq_mult(self):
|
||||
# normal freq to mult freq
|
||||
p = Period(freq='A', year=2007)
|
||||
# ordinal will not change
|
||||
for freq in ['3A', offsets.YearEnd(3)]:
|
||||
result = p.asfreq(freq)
|
||||
expected = Period('2007', freq='3A')
|
||||
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
# ordinal will not change
|
||||
for freq in ['3A', offsets.YearEnd(3)]:
|
||||
result = p.asfreq(freq, how='S')
|
||||
expected = Period('2007', freq='3A')
|
||||
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
|
||||
# mult freq to normal freq
|
||||
p = Period(freq='3A', year=2007)
|
||||
# ordinal will change because how=E is the default
|
||||
for freq in ['A', offsets.YearEnd()]:
|
||||
result = p.asfreq(freq)
|
||||
expected = Period('2009', freq='A')
|
||||
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
# ordinal will not change
|
||||
for freq in ['A', offsets.YearEnd()]:
|
||||
result = p.asfreq(freq, how='S')
|
||||
expected = Period('2007', freq='A')
|
||||
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
|
||||
p = Period(freq='A', year=2007)
|
||||
for freq in ['2M', offsets.MonthEnd(2)]:
|
||||
result = p.asfreq(freq)
|
||||
expected = Period('2007-12', freq='2M')
|
||||
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
for freq in ['2M', offsets.MonthEnd(2)]:
|
||||
result = p.asfreq(freq, how='S')
|
||||
expected = Period('2007-01', freq='2M')
|
||||
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
|
||||
p = Period(freq='3A', year=2007)
|
||||
for freq in ['2M', offsets.MonthEnd(2)]:
|
||||
result = p.asfreq(freq)
|
||||
expected = Period('2009-12', freq='2M')
|
||||
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
for freq in ['2M', offsets.MonthEnd(2)]:
|
||||
result = p.asfreq(freq, how='S')
|
||||
expected = Period('2007-01', freq='2M')
|
||||
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
|
||||
def test_asfreq_combined(self):
|
||||
# normal freq to combined freq
|
||||
p = Period('2007', freq='H')
|
||||
|
||||
# ordinal will not change
|
||||
expected = Period('2007', freq='25H')
|
||||
for freq, how in zip(['1D1H', '1H1D'], ['E', 'S']):
|
||||
result = p.asfreq(freq, how=how)
|
||||
assert result == expected
|
||||
assert result.ordinal == expected.ordinal
|
||||
assert result.freq == expected.freq
|
||||
|
||||
# combined freq to normal freq
|
||||
p1 = Period(freq='1D1H', year=2007)
|
||||
p2 = Period(freq='1H1D', year=2007)
|
||||
|
||||
# ordinal will change because how=E is the default
|
||||
result1 = p1.asfreq('H')
|
||||
result2 = p2.asfreq('H')
|
||||
expected = Period('2007-01-02', freq='H')
|
||||
assert result1 == expected
|
||||
assert result1.ordinal == expected.ordinal
|
||||
assert result1.freq == expected.freq
|
||||
assert result2 == expected
|
||||
assert result2.ordinal == expected.ordinal
|
||||
assert result2.freq == expected.freq
|
||||
|
||||
# ordinal will not change
|
||||
result1 = p1.asfreq('H', how='S')
|
||||
result2 = p2.asfreq('H', how='S')
|
||||
expected = Period('2007-01-01', freq='H')
|
||||
assert result1 == expected
|
||||
assert result1.ordinal == expected.ordinal
|
||||
assert result1.freq == expected.freq
|
||||
assert result2 == expected
|
||||
assert result2.ordinal == expected.ordinal
|
||||
assert result2.freq == expected.freq
|
||||
|
||||
def test_asfreq_MS(self):
|
||||
initial = Period("2013")
|
||||
|
||||
assert initial.asfreq(freq="M", how="S") == Period('2013-01', 'M')
|
||||
|
||||
msg = INVALID_FREQ_ERR_MSG
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
initial.asfreq(freq="MS", how="S")
|
||||
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Period('2013-01', 'MS')
|
||||
|
||||
assert _period_code_map.get("MS") is None
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,341 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
import pytz
|
||||
|
||||
from pandas._libs.tslibs import iNaT
|
||||
import pandas.compat as compat
|
||||
|
||||
from pandas import (
|
||||
DatetimeIndex, Index, NaT, Period, Series, Timedelta, TimedeltaIndex,
|
||||
Timestamp)
|
||||
from pandas.core.arrays import PeriodArray
|
||||
from pandas.util import testing as tm
|
||||
|
||||
|
||||
@pytest.mark.parametrize("nat,idx", [(Timestamp("NaT"), DatetimeIndex),
|
||||
(Timedelta("NaT"), TimedeltaIndex),
|
||||
(Period("NaT", freq="M"), PeriodArray)])
|
||||
def test_nat_fields(nat, idx):
|
||||
|
||||
for field in idx._field_ops:
|
||||
# weekday is a property of DTI, but a method
|
||||
# on NaT/Timestamp for compat with datetime
|
||||
if field == "weekday":
|
||||
continue
|
||||
|
||||
result = getattr(NaT, field)
|
||||
assert np.isnan(result)
|
||||
|
||||
result = getattr(nat, field)
|
||||
assert np.isnan(result)
|
||||
|
||||
for field in idx._bool_ops:
|
||||
|
||||
result = getattr(NaT, field)
|
||||
assert result is False
|
||||
|
||||
result = getattr(nat, field)
|
||||
assert result is False
|
||||
|
||||
|
||||
def test_nat_vector_field_access():
|
||||
idx = DatetimeIndex(["1/1/2000", None, None, "1/4/2000"])
|
||||
|
||||
for field in DatetimeIndex._field_ops:
|
||||
# weekday is a property of DTI, but a method
|
||||
# on NaT/Timestamp for compat with datetime
|
||||
if field == "weekday":
|
||||
continue
|
||||
|
||||
result = getattr(idx, field)
|
||||
expected = Index([getattr(x, field) for x in idx])
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
ser = Series(idx)
|
||||
|
||||
for field in DatetimeIndex._field_ops:
|
||||
# weekday is a property of DTI, but a method
|
||||
# on NaT/Timestamp for compat with datetime
|
||||
if field == "weekday":
|
||||
continue
|
||||
|
||||
result = getattr(ser.dt, field)
|
||||
expected = [getattr(x, field) for x in idx]
|
||||
tm.assert_series_equal(result, Series(expected))
|
||||
|
||||
for field in DatetimeIndex._bool_ops:
|
||||
result = getattr(ser.dt, field)
|
||||
expected = [getattr(x, field) for x in idx]
|
||||
tm.assert_series_equal(result, Series(expected))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("klass", [Timestamp, Timedelta, Period])
|
||||
@pytest.mark.parametrize("value", [None, np.nan, iNaT, float("nan"),
|
||||
NaT, "NaT", "nat"])
|
||||
def test_identity(klass, value):
|
||||
assert klass(value) is NaT
|
||||
|
||||
|
||||
@pytest.mark.parametrize("klass", [Timestamp, Timedelta, Period])
|
||||
@pytest.mark.parametrize("value", ["", "nat", "NAT", None, np.nan])
|
||||
def test_equality(klass, value):
|
||||
if klass is Period and value == "":
|
||||
pytest.skip("Period cannot parse empty string")
|
||||
|
||||
assert klass(value).value == iNaT
|
||||
|
||||
|
||||
@pytest.mark.parametrize("klass", [Timestamp, Timedelta])
|
||||
@pytest.mark.parametrize("method", ["round", "floor", "ceil"])
|
||||
@pytest.mark.parametrize("freq", ["s", "5s", "min", "5min", "h", "5h"])
|
||||
def test_round_nat(klass, method, freq):
|
||||
# see gh-14940
|
||||
ts = klass("nat")
|
||||
|
||||
round_method = getattr(ts, method)
|
||||
assert round_method(freq) is ts
|
||||
|
||||
|
||||
@pytest.mark.parametrize("method", [
|
||||
"astimezone", "combine", "ctime", "dst", "fromordinal",
|
||||
"fromtimestamp", "isocalendar", "strftime", "strptime",
|
||||
"time", "timestamp", "timetuple", "timetz", "toordinal",
|
||||
"tzname", "utcfromtimestamp", "utcnow", "utcoffset",
|
||||
"utctimetuple", "timestamp"
|
||||
])
|
||||
def test_nat_methods_raise(method):
|
||||
# see gh-9513, gh-17329
|
||||
msg = "NaTType does not support {method}".format(method=method)
|
||||
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
getattr(NaT, method)()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("method", [
|
||||
"weekday", "isoweekday"
|
||||
])
|
||||
def test_nat_methods_nan(method):
|
||||
# see gh-9513, gh-17329
|
||||
assert np.isnan(getattr(NaT, method)())
|
||||
|
||||
|
||||
@pytest.mark.parametrize("method", [
|
||||
"date", "now", "replace", "today",
|
||||
"tz_convert", "tz_localize"
|
||||
])
|
||||
def test_nat_methods_nat(method):
|
||||
# see gh-8254, gh-9513, gh-17329
|
||||
assert getattr(NaT, method)() is NaT
|
||||
|
||||
|
||||
@pytest.mark.parametrize("get_nat", [
|
||||
lambda x: NaT,
|
||||
lambda x: Timedelta(x),
|
||||
lambda x: Timestamp(x)
|
||||
])
|
||||
def test_nat_iso_format(get_nat):
|
||||
# see gh-12300
|
||||
assert get_nat("NaT").isoformat() == "NaT"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("klass,expected", [
|
||||
(Timestamp, ["freqstr", "normalize", "to_julian_date", "to_period", "tz"]),
|
||||
(Timedelta, ["components", "delta", "is_populated", "to_pytimedelta",
|
||||
"to_timedelta64", "view"])
|
||||
])
|
||||
def test_missing_public_nat_methods(klass, expected):
|
||||
# see gh-17327
|
||||
#
|
||||
# NaT should have *most* of the Timestamp and Timedelta methods.
|
||||
# Here, we check which public methods NaT does not have. We
|
||||
# ignore any missing private methods.
|
||||
nat_names = dir(NaT)
|
||||
klass_names = dir(klass)
|
||||
|
||||
missing = [x for x in klass_names if x not in nat_names and
|
||||
not x.startswith("_")]
|
||||
missing.sort()
|
||||
|
||||
assert missing == expected
|
||||
|
||||
|
||||
def _get_overlap_public_nat_methods(klass, as_tuple=False):
|
||||
"""
|
||||
Get overlapping public methods between NaT and another class.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
klass : type
|
||||
The class to compare with NaT
|
||||
as_tuple : bool, default False
|
||||
Whether to return a list of tuples of the form (klass, method).
|
||||
|
||||
Returns
|
||||
-------
|
||||
overlap : list
|
||||
"""
|
||||
nat_names = dir(NaT)
|
||||
klass_names = dir(klass)
|
||||
|
||||
overlap = [x for x in nat_names if x in klass_names and
|
||||
not x.startswith("_") and
|
||||
callable(getattr(klass, x))]
|
||||
|
||||
# Timestamp takes precedence over Timedelta in terms of overlap.
|
||||
if klass is Timedelta:
|
||||
ts_names = dir(Timestamp)
|
||||
overlap = [x for x in overlap if x not in ts_names]
|
||||
|
||||
if as_tuple:
|
||||
overlap = [(klass, method) for method in overlap]
|
||||
|
||||
overlap.sort()
|
||||
return overlap
|
||||
|
||||
|
||||
@pytest.mark.parametrize("klass,expected", [
|
||||
(Timestamp, ["astimezone", "ceil", "combine", "ctime", "date", "day_name",
|
||||
"dst", "floor", "fromisoformat", "fromordinal",
|
||||
"fromtimestamp", "isocalendar", "isoformat", "isoweekday",
|
||||
"month_name", "now", "replace", "round", "strftime",
|
||||
"strptime", "time", "timestamp", "timetuple", "timetz",
|
||||
"to_datetime64", "to_pydatetime", "today", "toordinal",
|
||||
"tz_convert", "tz_localize", "tzname", "utcfromtimestamp",
|
||||
"utcnow", "utcoffset", "utctimetuple", "weekday"]),
|
||||
(Timedelta, ["total_seconds"])
|
||||
])
|
||||
def test_overlap_public_nat_methods(klass, expected):
|
||||
# see gh-17327
|
||||
#
|
||||
# NaT should have *most* of the Timestamp and Timedelta methods.
|
||||
# In case when Timestamp, Timedelta, and NaT are overlap, the overlap
|
||||
# is considered to be with Timestamp and NaT, not Timedelta.
|
||||
|
||||
# "fromisoformat" was introduced in 3.7
|
||||
if klass is Timestamp and not compat.PY37:
|
||||
expected.remove("fromisoformat")
|
||||
|
||||
assert _get_overlap_public_nat_methods(klass) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("compare", (
|
||||
_get_overlap_public_nat_methods(Timestamp, True) +
|
||||
_get_overlap_public_nat_methods(Timedelta, True))
|
||||
)
|
||||
def test_nat_doc_strings(compare):
|
||||
# see gh-17327
|
||||
#
|
||||
# The docstrings for overlapping methods should match.
|
||||
klass, method = compare
|
||||
klass_doc = getattr(klass, method).__doc__
|
||||
|
||||
nat_doc = getattr(NaT, method).__doc__
|
||||
assert klass_doc == nat_doc
|
||||
|
||||
|
||||
_ops = {
|
||||
"left_plus_right": lambda a, b: a + b,
|
||||
"right_plus_left": lambda a, b: b + a,
|
||||
"left_minus_right": lambda a, b: a - b,
|
||||
"right_minus_left": lambda a, b: b - a,
|
||||
"left_times_right": lambda a, b: a * b,
|
||||
"right_times_left": lambda a, b: b * a,
|
||||
"left_div_right": lambda a, b: a / b,
|
||||
"right_div_left": lambda a, b: b / a,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("op_name", list(_ops.keys()))
|
||||
@pytest.mark.parametrize("value,val_type", [
|
||||
(2, "scalar"),
|
||||
(1.5, "scalar"),
|
||||
(np.nan, "scalar"),
|
||||
(timedelta(3600), "timedelta"),
|
||||
(Timedelta("5s"), "timedelta"),
|
||||
(datetime(2014, 1, 1), "timestamp"),
|
||||
(Timestamp("2014-01-01"), "timestamp"),
|
||||
(Timestamp("2014-01-01", tz="UTC"), "timestamp"),
|
||||
(Timestamp("2014-01-01", tz="US/Eastern"), "timestamp"),
|
||||
(pytz.timezone("Asia/Tokyo").localize(datetime(2014, 1, 1)), "timestamp"),
|
||||
])
|
||||
def test_nat_arithmetic_scalar(op_name, value, val_type):
|
||||
# see gh-6873
|
||||
invalid_ops = {
|
||||
"scalar": {"right_div_left"},
|
||||
"timedelta": {"left_times_right", "right_times_left"},
|
||||
"timestamp": {"left_times_right", "right_times_left",
|
||||
"left_div_right", "right_div_left"}
|
||||
}
|
||||
|
||||
op = _ops[op_name]
|
||||
|
||||
if op_name in invalid_ops.get(val_type, set()):
|
||||
if (val_type == "timedelta" and "times" in op_name and
|
||||
isinstance(value, Timedelta)):
|
||||
msg = "Cannot multiply"
|
||||
else:
|
||||
msg = "unsupported operand type"
|
||||
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
op(NaT, value)
|
||||
else:
|
||||
if val_type == "timedelta" and "div" in op_name:
|
||||
expected = np.nan
|
||||
else:
|
||||
expected = NaT
|
||||
|
||||
assert op(NaT, value) is expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("val,expected", [
|
||||
(np.nan, NaT),
|
||||
(NaT, np.nan),
|
||||
(np.timedelta64("NaT"), np.nan)
|
||||
])
|
||||
def test_nat_rfloordiv_timedelta(val, expected):
|
||||
# see gh-#18846
|
||||
#
|
||||
# See also test_timedelta.TestTimedeltaArithmetic.test_floordiv
|
||||
td = Timedelta(hours=3, minutes=4)
|
||||
assert td // val is expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("op_name", [
|
||||
"left_plus_right", "right_plus_left",
|
||||
"left_minus_right", "right_minus_left"
|
||||
])
|
||||
@pytest.mark.parametrize("value", [
|
||||
DatetimeIndex(["2011-01-01", "2011-01-02"], name="x"),
|
||||
DatetimeIndex(["2011-01-01", "2011-01-02"], name="x"),
|
||||
TimedeltaIndex(["1 day", "2 day"], name="x"),
|
||||
])
|
||||
def test_nat_arithmetic_index(op_name, value):
|
||||
# see gh-11718
|
||||
exp_name = "x"
|
||||
exp_data = [NaT] * 2
|
||||
|
||||
if isinstance(value, DatetimeIndex) and "plus" in op_name:
|
||||
expected = DatetimeIndex(exp_data, name=exp_name, tz=value.tz)
|
||||
else:
|
||||
expected = TimedeltaIndex(exp_data, name=exp_name)
|
||||
|
||||
tm.assert_index_equal(_ops[op_name](NaT, value), expected)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("op_name", [
|
||||
"left_plus_right", "right_plus_left",
|
||||
"left_minus_right", "right_minus_left"
|
||||
])
|
||||
@pytest.mark.parametrize("box", [TimedeltaIndex, Series])
|
||||
def test_nat_arithmetic_td64_vector(op_name, box):
|
||||
# see gh-19124
|
||||
vec = box(["1 day", "2 day"], dtype="timedelta64[ns]")
|
||||
box_nat = box([NaT, NaT], dtype="timedelta64[ns]")
|
||||
tm.assert_equal(_ops[op_name](vec, NaT), box_nat)
|
||||
|
||||
|
||||
def test_nat_pinned_docstrings():
|
||||
# see gh-17327
|
||||
assert NaT.ctime.__doc__ == datetime.ctime.__doc__
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+691
@@ -0,0 +1,691 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Tests for scalar Timedelta arithmetic ops
|
||||
"""
|
||||
from datetime import datetime, timedelta
|
||||
import operator
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
import pandas as pd
|
||||
from pandas import NaT, Timedelta, Timestamp
|
||||
from pandas.core import ops
|
||||
import pandas.util.testing as tm
|
||||
|
||||
|
||||
class TestTimedeltaAdditionSubtraction(object):
|
||||
"""
|
||||
Tests for Timedelta methods:
|
||||
|
||||
__add__, __radd__,
|
||||
__sub__, __rsub__
|
||||
"""
|
||||
@pytest.mark.parametrize('ten_seconds', [
|
||||
Timedelta(10, unit='s'),
|
||||
timedelta(seconds=10),
|
||||
np.timedelta64(10, 's'),
|
||||
np.timedelta64(10000000000, 'ns'),
|
||||
pd.offsets.Second(10)])
|
||||
def test_td_add_sub_ten_seconds(self, ten_seconds):
|
||||
# GH#6808
|
||||
base = Timestamp('20130101 09:01:12.123456')
|
||||
expected_add = Timestamp('20130101 09:01:22.123456')
|
||||
expected_sub = Timestamp('20130101 09:01:02.123456')
|
||||
|
||||
result = base + ten_seconds
|
||||
assert result == expected_add
|
||||
|
||||
result = base - ten_seconds
|
||||
assert result == expected_sub
|
||||
|
||||
@pytest.mark.parametrize('one_day_ten_secs', [
|
||||
Timedelta('1 day, 00:00:10'),
|
||||
Timedelta('1 days, 00:00:10'),
|
||||
timedelta(days=1, seconds=10),
|
||||
np.timedelta64(1, 'D') + np.timedelta64(10, 's'),
|
||||
pd.offsets.Day() + pd.offsets.Second(10)])
|
||||
def test_td_add_sub_one_day_ten_seconds(self, one_day_ten_secs):
|
||||
# GH#6808
|
||||
base = Timestamp('20130102 09:01:12.123456')
|
||||
expected_add = Timestamp('20130103 09:01:22.123456')
|
||||
expected_sub = Timestamp('20130101 09:01:02.123456')
|
||||
|
||||
result = base + one_day_ten_secs
|
||||
assert result == expected_add
|
||||
|
||||
result = base - one_day_ten_secs
|
||||
assert result == expected_sub
|
||||
|
||||
@pytest.mark.parametrize('op', [operator.add, ops.radd])
|
||||
def test_td_add_datetimelike_scalar(self, op):
|
||||
# GH#19738
|
||||
td = Timedelta(10, unit='d')
|
||||
|
||||
result = op(td, datetime(2016, 1, 1))
|
||||
if op is operator.add:
|
||||
# datetime + Timedelta does _not_ call Timedelta.__radd__,
|
||||
# so we get a datetime back instead of a Timestamp
|
||||
assert isinstance(result, Timestamp)
|
||||
assert result == Timestamp(2016, 1, 11)
|
||||
|
||||
result = op(td, Timestamp('2018-01-12 18:09'))
|
||||
assert isinstance(result, Timestamp)
|
||||
assert result == Timestamp('2018-01-22 18:09')
|
||||
|
||||
result = op(td, np.datetime64('2018-01-12'))
|
||||
assert isinstance(result, Timestamp)
|
||||
assert result == Timestamp('2018-01-22')
|
||||
|
||||
result = op(td, NaT)
|
||||
assert result is NaT
|
||||
|
||||
@pytest.mark.parametrize('op', [operator.add, ops.radd])
|
||||
def test_td_add_td(self, op):
|
||||
td = Timedelta(10, unit='d')
|
||||
|
||||
result = op(td, Timedelta(days=10))
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(days=20)
|
||||
|
||||
@pytest.mark.parametrize('op', [operator.add, ops.radd])
|
||||
def test_td_add_pytimedelta(self, op):
|
||||
td = Timedelta(10, unit='d')
|
||||
result = op(td, timedelta(days=9))
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(days=19)
|
||||
|
||||
@pytest.mark.parametrize('op', [operator.add, ops.radd])
|
||||
def test_td_add_timedelta64(self, op):
|
||||
td = Timedelta(10, unit='d')
|
||||
result = op(td, np.timedelta64(-4, 'D'))
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(days=6)
|
||||
|
||||
@pytest.mark.parametrize('op', [operator.add, ops.radd])
|
||||
def test_td_add_offset(self, op):
|
||||
td = Timedelta(10, unit='d')
|
||||
|
||||
result = op(td, pd.offsets.Hour(6))
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(days=10, hours=6)
|
||||
|
||||
def test_td_sub_td(self):
|
||||
td = Timedelta(10, unit='d')
|
||||
expected = Timedelta(0, unit='ns')
|
||||
result = td - td
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == expected
|
||||
|
||||
def test_td_sub_pytimedelta(self):
|
||||
td = Timedelta(10, unit='d')
|
||||
expected = Timedelta(0, unit='ns')
|
||||
|
||||
result = td - td.to_pytimedelta()
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == expected
|
||||
|
||||
result = td.to_pytimedelta() - td
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == expected
|
||||
|
||||
def test_td_sub_timedelta64(self):
|
||||
td = Timedelta(10, unit='d')
|
||||
expected = Timedelta(0, unit='ns')
|
||||
|
||||
result = td - td.to_timedelta64()
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == expected
|
||||
|
||||
result = td.to_timedelta64() - td
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == expected
|
||||
|
||||
def test_td_sub_nat(self):
|
||||
# In this context pd.NaT is treated as timedelta-like
|
||||
td = Timedelta(10, unit='d')
|
||||
result = td - NaT
|
||||
assert result is NaT
|
||||
|
||||
def test_td_sub_td64_nat(self):
|
||||
td = Timedelta(10, unit='d')
|
||||
td_nat = np.timedelta64('NaT')
|
||||
|
||||
result = td - td_nat
|
||||
assert result is NaT
|
||||
|
||||
result = td_nat - td
|
||||
assert result is NaT
|
||||
|
||||
def test_td_sub_offset(self):
|
||||
td = Timedelta(10, unit='d')
|
||||
result = td - pd.offsets.Hour(1)
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(239, unit='h')
|
||||
|
||||
def test_td_add_sub_numeric_raises(self):
|
||||
td = Timedelta(10, unit='d')
|
||||
for other in [2, 2.0, np.int64(2), np.float64(2)]:
|
||||
with pytest.raises(TypeError):
|
||||
td + other
|
||||
with pytest.raises(TypeError):
|
||||
other + td
|
||||
with pytest.raises(TypeError):
|
||||
td - other
|
||||
with pytest.raises(TypeError):
|
||||
other - td
|
||||
|
||||
def test_td_rsub_nat(self):
|
||||
td = Timedelta(10, unit='d')
|
||||
result = NaT - td
|
||||
assert result is NaT
|
||||
|
||||
result = np.datetime64('NaT') - td
|
||||
assert result is NaT
|
||||
|
||||
def test_td_rsub_offset(self):
|
||||
result = pd.offsets.Hour(1) - Timedelta(10, unit='d')
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(-239, unit='h')
|
||||
|
||||
def test_td_sub_timedeltalike_object_dtype_array(self):
|
||||
# GH#21980
|
||||
arr = np.array([Timestamp('20130101 9:01'),
|
||||
Timestamp('20121230 9:02')])
|
||||
exp = np.array([Timestamp('20121231 9:01'),
|
||||
Timestamp('20121229 9:02')])
|
||||
res = arr - Timedelta('1D')
|
||||
tm.assert_numpy_array_equal(res, exp)
|
||||
|
||||
def test_td_sub_mixed_most_timedeltalike_object_dtype_array(self):
|
||||
# GH#21980
|
||||
now = Timestamp.now()
|
||||
arr = np.array([now,
|
||||
Timedelta('1D'),
|
||||
np.timedelta64(2, 'h')])
|
||||
exp = np.array([now - Timedelta('1D'),
|
||||
Timedelta('0D'),
|
||||
np.timedelta64(2, 'h') - Timedelta('1D')])
|
||||
res = arr - Timedelta('1D')
|
||||
tm.assert_numpy_array_equal(res, exp)
|
||||
|
||||
def test_td_rsub_mixed_most_timedeltalike_object_dtype_array(self):
|
||||
# GH#21980
|
||||
now = Timestamp.now()
|
||||
arr = np.array([now,
|
||||
Timedelta('1D'),
|
||||
np.timedelta64(2, 'h')])
|
||||
with pytest.raises(TypeError):
|
||||
Timedelta('1D') - arr
|
||||
|
||||
@pytest.mark.parametrize('op', [operator.add, ops.radd])
|
||||
def test_td_add_timedeltalike_object_dtype_array(self, op):
|
||||
# GH#21980
|
||||
arr = np.array([Timestamp('20130101 9:01'),
|
||||
Timestamp('20121230 9:02')])
|
||||
exp = np.array([Timestamp('20130102 9:01'),
|
||||
Timestamp('20121231 9:02')])
|
||||
res = op(arr, Timedelta('1D'))
|
||||
tm.assert_numpy_array_equal(res, exp)
|
||||
|
||||
@pytest.mark.parametrize('op', [operator.add, ops.radd])
|
||||
def test_td_add_mixed_timedeltalike_object_dtype_array(self, op):
|
||||
# GH#21980
|
||||
now = Timestamp.now()
|
||||
arr = np.array([now,
|
||||
Timedelta('1D')])
|
||||
exp = np.array([now + Timedelta('1D'),
|
||||
Timedelta('2D')])
|
||||
res = op(arr, Timedelta('1D'))
|
||||
tm.assert_numpy_array_equal(res, exp)
|
||||
|
||||
|
||||
class TestTimedeltaMultiplicationDivision(object):
|
||||
"""
|
||||
Tests for Timedelta methods:
|
||||
|
||||
__mul__, __rmul__,
|
||||
__div__, __rdiv__,
|
||||
__truediv__, __rtruediv__,
|
||||
__floordiv__, __rfloordiv__,
|
||||
__mod__, __rmod__,
|
||||
__divmod__, __rdivmod__
|
||||
"""
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Timedelta.__mul__, __rmul__
|
||||
|
||||
@pytest.mark.parametrize('td_nat', [NaT,
|
||||
np.timedelta64('NaT', 'ns'),
|
||||
np.timedelta64('NaT')])
|
||||
@pytest.mark.parametrize('op', [operator.mul, ops.rmul])
|
||||
def test_td_mul_nat(self, op, td_nat):
|
||||
# GH#19819
|
||||
td = Timedelta(10, unit='d')
|
||||
with pytest.raises(TypeError):
|
||||
op(td, td_nat)
|
||||
|
||||
@pytest.mark.parametrize('nan', [np.nan, np.float64('NaN'), float('nan')])
|
||||
@pytest.mark.parametrize('op', [operator.mul, ops.rmul])
|
||||
def test_td_mul_nan(self, op, nan):
|
||||
# np.float64('NaN') has a 'dtype' attr, avoid treating as array
|
||||
td = Timedelta(10, unit='d')
|
||||
result = op(td, nan)
|
||||
assert result is NaT
|
||||
|
||||
@pytest.mark.parametrize('op', [operator.mul, ops.rmul])
|
||||
def test_td_mul_scalar(self, op):
|
||||
# GH#19738
|
||||
td = Timedelta(minutes=3)
|
||||
|
||||
result = op(td, 2)
|
||||
assert result == Timedelta(minutes=6)
|
||||
|
||||
result = op(td, 1.5)
|
||||
assert result == Timedelta(minutes=4, seconds=30)
|
||||
|
||||
assert op(td, np.nan) is NaT
|
||||
|
||||
assert op(-1, td).value == -1 * td.value
|
||||
assert op(-1.0, td).value == -1.0 * td.value
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
# timedelta * datetime is gibberish
|
||||
op(td, Timestamp(2016, 1, 2))
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
# invalid multiply with another timedelta
|
||||
op(td, td)
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Timedelta.__div__, __truediv__
|
||||
|
||||
def test_td_div_timedeltalike_scalar(self):
|
||||
# GH#19738
|
||||
td = Timedelta(10, unit='d')
|
||||
|
||||
result = td / pd.offsets.Hour(1)
|
||||
assert result == 240
|
||||
|
||||
assert td / td == 1
|
||||
assert td / np.timedelta64(60, 'h') == 4
|
||||
|
||||
assert np.isnan(td / NaT)
|
||||
|
||||
def test_td_div_numeric_scalar(self):
|
||||
# GH#19738
|
||||
td = Timedelta(10, unit='d')
|
||||
|
||||
result = td / 2
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(days=5)
|
||||
|
||||
result = td / 5.0
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(days=2)
|
||||
|
||||
@pytest.mark.parametrize('nan', [np.nan, np.float64('NaN'), float('nan')])
|
||||
def test_td_div_nan(self, nan):
|
||||
# np.float64('NaN') has a 'dtype' attr, avoid treating as array
|
||||
td = Timedelta(10, unit='d')
|
||||
result = td / nan
|
||||
assert result is NaT
|
||||
|
||||
result = td // nan
|
||||
assert result is NaT
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Timedelta.__rdiv__
|
||||
|
||||
def test_td_rdiv_timedeltalike_scalar(self):
|
||||
# GH#19738
|
||||
td = Timedelta(10, unit='d')
|
||||
result = pd.offsets.Hour(1) / td
|
||||
assert result == 1 / 240.0
|
||||
|
||||
assert np.timedelta64(60, 'h') / td == 0.25
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Timedelta.__floordiv__
|
||||
|
||||
def test_td_floordiv_timedeltalike_scalar(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=4)
|
||||
scalar = Timedelta(hours=3, minutes=3)
|
||||
|
||||
assert td // scalar == 1
|
||||
assert -td // scalar.to_pytimedelta() == -2
|
||||
assert (2 * td) // scalar.to_timedelta64() == 2
|
||||
|
||||
def test_td_floordiv_null_scalar(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=4)
|
||||
|
||||
assert td // np.nan is NaT
|
||||
assert np.isnan(td // NaT)
|
||||
assert np.isnan(td // np.timedelta64('NaT'))
|
||||
|
||||
def test_td_floordiv_offsets(self):
|
||||
# GH#19738
|
||||
td = Timedelta(hours=3, minutes=4)
|
||||
assert td // pd.offsets.Hour(1) == 3
|
||||
assert td // pd.offsets.Minute(2) == 92
|
||||
|
||||
def test_td_floordiv_invalid_scalar(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=4)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
td // np.datetime64('2016-01-01', dtype='datetime64[us]')
|
||||
|
||||
def test_td_floordiv_numeric_scalar(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=4)
|
||||
|
||||
expected = Timedelta(hours=1, minutes=32)
|
||||
assert td // 2 == expected
|
||||
assert td // 2.0 == expected
|
||||
assert td // np.float64(2.0) == expected
|
||||
assert td // np.int32(2.0) == expected
|
||||
assert td // np.uint8(2.0) == expected
|
||||
|
||||
def test_td_floordiv_timedeltalike_array(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=4)
|
||||
scalar = Timedelta(hours=3, minutes=3)
|
||||
|
||||
# Array-like others
|
||||
assert td // np.array(scalar.to_timedelta64()) == 1
|
||||
|
||||
res = (3 * td) // np.array([scalar.to_timedelta64()])
|
||||
expected = np.array([3], dtype=np.int64)
|
||||
tm.assert_numpy_array_equal(res, expected)
|
||||
|
||||
res = (10 * td) // np.array([scalar.to_timedelta64(),
|
||||
np.timedelta64('NaT')])
|
||||
expected = np.array([10, np.nan])
|
||||
tm.assert_numpy_array_equal(res, expected)
|
||||
|
||||
def test_td_floordiv_numeric_series(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=4)
|
||||
ser = pd.Series([1], dtype=np.int64)
|
||||
res = td // ser
|
||||
assert res.dtype.kind == 'm'
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Timedelta.__rfloordiv__
|
||||
|
||||
def test_td_rfloordiv_timedeltalike_scalar(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=3)
|
||||
scalar = Timedelta(hours=3, minutes=4)
|
||||
|
||||
# scalar others
|
||||
# x // Timedelta is defined only for timedelta-like x. int-like,
|
||||
# float-like, and date-like, in particular, should all either
|
||||
# a) raise TypeError directly or
|
||||
# b) return NotImplemented, following which the reversed
|
||||
# operation will raise TypeError.
|
||||
assert td.__rfloordiv__(scalar) == 1
|
||||
assert (-td).__rfloordiv__(scalar.to_pytimedelta()) == -2
|
||||
assert (2 * td).__rfloordiv__(scalar.to_timedelta64()) == 0
|
||||
|
||||
def test_td_rfloordiv_null_scalar(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=3)
|
||||
|
||||
assert np.isnan(td.__rfloordiv__(NaT))
|
||||
assert np.isnan(td.__rfloordiv__(np.timedelta64('NaT')))
|
||||
|
||||
def test_td_rfloordiv_offsets(self):
|
||||
# GH#19738
|
||||
assert pd.offsets.Hour(1) // Timedelta(minutes=25) == 2
|
||||
|
||||
def test_td_rfloordiv_invalid_scalar(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=3)
|
||||
|
||||
dt64 = np.datetime64('2016-01-01', dtype='datetime64[us]')
|
||||
with pytest.raises(TypeError):
|
||||
td.__rfloordiv__(dt64)
|
||||
|
||||
def test_td_rfloordiv_numeric_scalar(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=3)
|
||||
|
||||
assert td.__rfloordiv__(np.nan) is NotImplemented
|
||||
assert td.__rfloordiv__(3.5) is NotImplemented
|
||||
assert td.__rfloordiv__(2) is NotImplemented
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
td.__rfloordiv__(np.float64(2.0))
|
||||
with pytest.raises(TypeError):
|
||||
td.__rfloordiv__(np.uint8(9))
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# GH-19761: Change to TypeError.
|
||||
td.__rfloordiv__(np.int32(2.0))
|
||||
|
||||
def test_td_rfloordiv_timedeltalike_array(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=3)
|
||||
scalar = Timedelta(hours=3, minutes=4)
|
||||
|
||||
# Array-like others
|
||||
assert td.__rfloordiv__(np.array(scalar.to_timedelta64())) == 1
|
||||
|
||||
res = td.__rfloordiv__(np.array([(3 * scalar).to_timedelta64()]))
|
||||
expected = np.array([3], dtype=np.int64)
|
||||
tm.assert_numpy_array_equal(res, expected)
|
||||
|
||||
arr = np.array([(10 * scalar).to_timedelta64(),
|
||||
np.timedelta64('NaT')])
|
||||
res = td.__rfloordiv__(arr)
|
||||
expected = np.array([10, np.nan])
|
||||
tm.assert_numpy_array_equal(res, expected)
|
||||
|
||||
def test_td_rfloordiv_numeric_series(self):
|
||||
# GH#18846
|
||||
td = Timedelta(hours=3, minutes=3)
|
||||
ser = pd.Series([1], dtype=np.int64)
|
||||
res = td.__rfloordiv__(ser)
|
||||
assert res is NotImplemented
|
||||
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
|
||||
# TODO: GH-19761. Change to TypeError.
|
||||
ser // td
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Timedelta.__mod__, __rmod__
|
||||
|
||||
def test_mod_timedeltalike(self):
|
||||
# GH#19365
|
||||
td = Timedelta(hours=37)
|
||||
|
||||
# Timedelta-like others
|
||||
result = td % Timedelta(hours=6)
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(hours=1)
|
||||
|
||||
result = td % timedelta(minutes=60)
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(0)
|
||||
|
||||
result = td % NaT
|
||||
assert result is NaT
|
||||
|
||||
def test_mod_timedelta64_nat(self):
|
||||
# GH#19365
|
||||
td = Timedelta(hours=37)
|
||||
|
||||
result = td % np.timedelta64('NaT', 'ns')
|
||||
assert result is NaT
|
||||
|
||||
def test_mod_timedelta64(self):
|
||||
# GH#19365
|
||||
td = Timedelta(hours=37)
|
||||
|
||||
result = td % np.timedelta64(2, 'h')
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(hours=1)
|
||||
|
||||
def test_mod_offset(self):
|
||||
# GH#19365
|
||||
td = Timedelta(hours=37)
|
||||
|
||||
result = td % pd.offsets.Hour(5)
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(hours=2)
|
||||
|
||||
def test_mod_numeric(self):
|
||||
# GH#19365
|
||||
td = Timedelta(hours=37)
|
||||
|
||||
# Numeric Others
|
||||
result = td % 2
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(0)
|
||||
|
||||
result = td % 1e12
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(minutes=3, seconds=20)
|
||||
|
||||
result = td % int(1e12)
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(minutes=3, seconds=20)
|
||||
|
||||
def test_mod_invalid(self):
|
||||
# GH#19365
|
||||
td = Timedelta(hours=37)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
td % Timestamp('2018-01-22')
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
td % []
|
||||
|
||||
def test_rmod_pytimedelta(self):
|
||||
# GH#19365
|
||||
td = Timedelta(minutes=3)
|
||||
|
||||
result = timedelta(minutes=4) % td
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(minutes=1)
|
||||
|
||||
def test_rmod_timedelta64(self):
|
||||
# GH#19365
|
||||
td = Timedelta(minutes=3)
|
||||
result = np.timedelta64(5, 'm') % td
|
||||
assert isinstance(result, Timedelta)
|
||||
assert result == Timedelta(minutes=2)
|
||||
|
||||
def test_rmod_invalid(self):
|
||||
# GH#19365
|
||||
td = Timedelta(minutes=3)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
Timestamp('2018-01-22') % td
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
15 % td
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
16.0 % td
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
np.array([22, 24]) % td
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Timedelta.__divmod__, __rdivmod__
|
||||
|
||||
def test_divmod_numeric(self):
|
||||
# GH#19365
|
||||
td = Timedelta(days=2, hours=6)
|
||||
|
||||
result = divmod(td, 53 * 3600 * 1e9)
|
||||
assert result[0] == Timedelta(1, unit='ns')
|
||||
assert isinstance(result[1], Timedelta)
|
||||
assert result[1] == Timedelta(hours=1)
|
||||
|
||||
assert result
|
||||
result = divmod(td, np.nan)
|
||||
assert result[0] is NaT
|
||||
assert result[1] is NaT
|
||||
|
||||
def test_divmod(self):
|
||||
# GH#19365
|
||||
td = Timedelta(days=2, hours=6)
|
||||
|
||||
result = divmod(td, timedelta(days=1))
|
||||
assert result[0] == 2
|
||||
assert isinstance(result[1], Timedelta)
|
||||
assert result[1] == Timedelta(hours=6)
|
||||
|
||||
result = divmod(td, 54)
|
||||
assert result[0] == Timedelta(hours=1)
|
||||
assert isinstance(result[1], Timedelta)
|
||||
assert result[1] == Timedelta(0)
|
||||
|
||||
result = divmod(td, NaT)
|
||||
assert np.isnan(result[0])
|
||||
assert result[1] is NaT
|
||||
|
||||
def test_divmod_offset(self):
|
||||
# GH#19365
|
||||
td = Timedelta(days=2, hours=6)
|
||||
|
||||
result = divmod(td, pd.offsets.Hour(-4))
|
||||
assert result[0] == -14
|
||||
assert isinstance(result[1], Timedelta)
|
||||
assert result[1] == Timedelta(hours=-2)
|
||||
|
||||
def test_divmod_invalid(self):
|
||||
# GH#19365
|
||||
td = Timedelta(days=2, hours=6)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
divmod(td, Timestamp('2018-01-22'))
|
||||
|
||||
def test_rdivmod_pytimedelta(self):
|
||||
# GH#19365
|
||||
result = divmod(timedelta(days=2, hours=6), Timedelta(days=1))
|
||||
assert result[0] == 2
|
||||
assert isinstance(result[1], Timedelta)
|
||||
assert result[1] == Timedelta(hours=6)
|
||||
|
||||
def test_rdivmod_offset(self):
|
||||
result = divmod(pd.offsets.Hour(54), Timedelta(hours=-4))
|
||||
assert result[0] == -14
|
||||
assert isinstance(result[1], Timedelta)
|
||||
assert result[1] == Timedelta(hours=-2)
|
||||
|
||||
def test_rdivmod_invalid(self):
|
||||
# GH#19365
|
||||
td = Timedelta(minutes=3)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
divmod(Timestamp('2018-01-22'), td)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
divmod(15, td)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
divmod(16.0, td)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
divmod(np.array([22, 24]), td)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
@pytest.mark.parametrize('op', [
|
||||
operator.mul,
|
||||
ops.rmul,
|
||||
operator.truediv,
|
||||
ops.rdiv,
|
||||
ops.rsub])
|
||||
@pytest.mark.parametrize('arr', [
|
||||
np.array([Timestamp('20130101 9:01'), Timestamp('20121230 9:02')]),
|
||||
np.array([Timestamp.now(), Timedelta('1D')])
|
||||
])
|
||||
def test_td_op_timedelta_timedeltalike_array(self, op, arr):
|
||||
with pytest.raises(TypeError):
|
||||
op(arr, Timedelta('1D'))
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from datetime import timedelta
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas import Timedelta, offsets, to_timedelta
|
||||
|
||||
|
||||
def test_construction():
|
||||
expected = np.timedelta64(10, 'D').astype('m8[ns]').view('i8')
|
||||
assert Timedelta(10, unit='d').value == expected
|
||||
assert Timedelta(10.0, unit='d').value == expected
|
||||
assert Timedelta('10 days').value == expected
|
||||
assert Timedelta(days=10).value == expected
|
||||
assert Timedelta(days=10.0).value == expected
|
||||
|
||||
expected += np.timedelta64(10, 's').astype('m8[ns]').view('i8')
|
||||
assert Timedelta('10 days 00:00:10').value == expected
|
||||
assert Timedelta(days=10, seconds=10).value == expected
|
||||
assert Timedelta(days=10, milliseconds=10 * 1000).value == expected
|
||||
assert Timedelta(days=10,
|
||||
microseconds=10 * 1000 * 1000).value == expected
|
||||
|
||||
# rounding cases
|
||||
assert Timedelta(82739999850000).value == 82739999850000
|
||||
assert ('0 days 22:58:59.999850' in str(Timedelta(82739999850000)))
|
||||
assert Timedelta(123072001000000).value == 123072001000000
|
||||
assert ('1 days 10:11:12.001' in str(Timedelta(123072001000000)))
|
||||
|
||||
# string conversion with/without leading zero
|
||||
# GH#9570
|
||||
assert Timedelta('0:00:00') == timedelta(hours=0)
|
||||
assert Timedelta('00:00:00') == timedelta(hours=0)
|
||||
assert Timedelta('-1:00:00') == -timedelta(hours=1)
|
||||
assert Timedelta('-01:00:00') == -timedelta(hours=1)
|
||||
|
||||
# more strings & abbrevs
|
||||
# GH#8190
|
||||
assert Timedelta('1 h') == timedelta(hours=1)
|
||||
assert Timedelta('1 hour') == timedelta(hours=1)
|
||||
assert Timedelta('1 hr') == timedelta(hours=1)
|
||||
assert Timedelta('1 hours') == timedelta(hours=1)
|
||||
assert Timedelta('-1 hours') == -timedelta(hours=1)
|
||||
assert Timedelta('1 m') == timedelta(minutes=1)
|
||||
assert Timedelta('1.5 m') == timedelta(seconds=90)
|
||||
assert Timedelta('1 minute') == timedelta(minutes=1)
|
||||
assert Timedelta('1 minutes') == timedelta(minutes=1)
|
||||
assert Timedelta('1 s') == timedelta(seconds=1)
|
||||
assert Timedelta('1 second') == timedelta(seconds=1)
|
||||
assert Timedelta('1 seconds') == timedelta(seconds=1)
|
||||
assert Timedelta('1 ms') == timedelta(milliseconds=1)
|
||||
assert Timedelta('1 milli') == timedelta(milliseconds=1)
|
||||
assert Timedelta('1 millisecond') == timedelta(milliseconds=1)
|
||||
assert Timedelta('1 us') == timedelta(microseconds=1)
|
||||
assert Timedelta('1 micros') == timedelta(microseconds=1)
|
||||
assert Timedelta('1 microsecond') == timedelta(microseconds=1)
|
||||
assert Timedelta('1.5 microsecond') == Timedelta('00:00:00.000001500')
|
||||
assert Timedelta('1 ns') == Timedelta('00:00:00.000000001')
|
||||
assert Timedelta('1 nano') == Timedelta('00:00:00.000000001')
|
||||
assert Timedelta('1 nanosecond') == Timedelta('00:00:00.000000001')
|
||||
|
||||
# combos
|
||||
assert Timedelta('10 days 1 hour') == timedelta(days=10, hours=1)
|
||||
assert Timedelta('10 days 1 h') == timedelta(days=10, hours=1)
|
||||
assert Timedelta('10 days 1 h 1m 1s') == timedelta(
|
||||
days=10, hours=1, minutes=1, seconds=1)
|
||||
assert Timedelta('-10 days 1 h 1m 1s') == -timedelta(
|
||||
days=10, hours=1, minutes=1, seconds=1)
|
||||
assert Timedelta('-10 days 1 h 1m 1s') == -timedelta(
|
||||
days=10, hours=1, minutes=1, seconds=1)
|
||||
assert Timedelta('-10 days 1 h 1m 1s 3us') == -timedelta(
|
||||
days=10, hours=1, minutes=1, seconds=1, microseconds=3)
|
||||
assert Timedelta('-10 days 1 h 1.5m 1s 3us') == -timedelta(
|
||||
days=10, hours=1, minutes=1, seconds=31, microseconds=3)
|
||||
|
||||
# Currently invalid as it has a - on the hh:mm:dd part
|
||||
# (only allowed on the days)
|
||||
with pytest.raises(ValueError):
|
||||
Timedelta('-10 days -1 h 1.5m 1s 3us')
|
||||
|
||||
# only leading neg signs are allowed
|
||||
with pytest.raises(ValueError):
|
||||
Timedelta('10 days -1 h 1.5m 1s 3us')
|
||||
|
||||
# no units specified
|
||||
with pytest.raises(ValueError):
|
||||
Timedelta('3.1415')
|
||||
|
||||
# invalid construction
|
||||
with pytest.raises(ValueError, match="cannot construct a Timedelta"):
|
||||
Timedelta()
|
||||
|
||||
with pytest.raises(ValueError, match="unit abbreviation w/o a number"):
|
||||
Timedelta('foo')
|
||||
|
||||
msg = ("cannot construct a Timedelta from "
|
||||
"the passed arguments, allowed keywords are ")
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
Timedelta(day=10)
|
||||
|
||||
# floats
|
||||
expected = np.timedelta64(
|
||||
10, 's').astype('m8[ns]').view('i8') + np.timedelta64(
|
||||
500, 'ms').astype('m8[ns]').view('i8')
|
||||
assert Timedelta(10.5, unit='s').value == expected
|
||||
|
||||
# offset
|
||||
assert to_timedelta(offsets.Hour(2)) == Timedelta(hours=2)
|
||||
assert Timedelta(offsets.Hour(2)) == Timedelta(hours=2)
|
||||
assert Timedelta(offsets.Second(2)) == Timedelta(seconds=2)
|
||||
|
||||
# GH#11995: unicode
|
||||
expected = Timedelta('1H')
|
||||
result = Timedelta(u'1H')
|
||||
assert result == expected
|
||||
assert to_timedelta(offsets.Hour(2)) == Timedelta(u'0 days, 02:00:00')
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
Timedelta(u'foo bar')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('item', list({'days': 'D',
|
||||
'seconds': 's',
|
||||
'microseconds': 'us',
|
||||
'milliseconds': 'ms',
|
||||
'minutes': 'm',
|
||||
'hours': 'h',
|
||||
'weeks': 'W'}.items()))
|
||||
@pytest.mark.parametrize('npdtype', [np.int64, np.int32, np.int16,
|
||||
np.float64, np.float32, np.float16])
|
||||
def test_td_construction_with_np_dtypes(npdtype, item):
|
||||
# GH#8757: test construction with np dtypes
|
||||
pykwarg, npkwarg = item
|
||||
expected = np.timedelta64(1, npkwarg).astype('m8[ns]').view('i8')
|
||||
assert Timedelta(**{pykwarg: npdtype(1)}).value == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('val', [
|
||||
'1s', '-1s', '1us', '-1us', '1 day', '-1 day',
|
||||
'-23:59:59.999999', '-1 days +23:59:59.999999', '-1ns',
|
||||
'1ns', '-23:59:59.999999999'])
|
||||
def test_td_from_repr_roundtrip(val):
|
||||
# round-trip both for string and value
|
||||
td = Timedelta(val)
|
||||
assert Timedelta(td.value) == td
|
||||
|
||||
# str does not normally display nanos
|
||||
if not td.nanoseconds:
|
||||
assert Timedelta(str(td)) == td
|
||||
assert Timedelta(td._repr_base(format='all')) == td
|
||||
|
||||
|
||||
def test_overflow_on_construction():
|
||||
# GH#3374
|
||||
value = Timedelta('1day').value * 20169940
|
||||
with pytest.raises(OverflowError):
|
||||
Timedelta(value)
|
||||
|
||||
# xref GH#17637
|
||||
with pytest.raises(OverflowError):
|
||||
Timedelta(7 * 19999, unit='D')
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
Timedelta(timedelta(days=13 * 19999))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fmt,exp', [
|
||||
('P6DT0H50M3.010010012S', Timedelta(days=6, minutes=50, seconds=3,
|
||||
milliseconds=10, microseconds=10,
|
||||
nanoseconds=12)),
|
||||
('P-6DT0H50M3.010010012S', Timedelta(days=-6, minutes=50, seconds=3,
|
||||
milliseconds=10, microseconds=10,
|
||||
nanoseconds=12)),
|
||||
('P4DT12H30M5S', Timedelta(days=4, hours=12, minutes=30, seconds=5)),
|
||||
('P0DT0H0M0.000000123S', Timedelta(nanoseconds=123)),
|
||||
('P0DT0H0M0.00001S', Timedelta(microseconds=10)),
|
||||
('P0DT0H0M0.001S', Timedelta(milliseconds=1)),
|
||||
('P0DT0H1M0S', Timedelta(minutes=1)),
|
||||
('P1DT25H61M61S', Timedelta(days=1, hours=25, minutes=61, seconds=61))
|
||||
])
|
||||
def test_iso_constructor(fmt, exp):
|
||||
assert Timedelta(fmt) == exp
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fmt', [
|
||||
'PPPPPPPPPPPP', 'PDTHMS', 'P0DT999H999M999S',
|
||||
'P1DT0H0M0.0000000000000S', 'P1DT0H0M00000000000S',
|
||||
'P1DT0H0M0.S'])
|
||||
def test_iso_constructor_raises(fmt):
|
||||
with pytest.raises(ValueError, match=('Invalid ISO 8601 Duration '
|
||||
'format - {}'.format(fmt))):
|
||||
Timedelta(fmt)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('constructed_td, conversion', [
|
||||
(Timedelta(nanoseconds=100), '100ns'),
|
||||
(Timedelta(days=1, hours=1, minutes=1, weeks=1, seconds=1, milliseconds=1,
|
||||
microseconds=1, nanoseconds=1), 694861001001001),
|
||||
(Timedelta(microseconds=1) + Timedelta(nanoseconds=1), '1us1ns'),
|
||||
(Timedelta(microseconds=1) - Timedelta(nanoseconds=1), '999ns'),
|
||||
(Timedelta(microseconds=1) + 5 * Timedelta(nanoseconds=-2), '990ns')])
|
||||
def test_td_constructor_on_nanoseconds(constructed_td, conversion):
|
||||
# GH#9273
|
||||
assert constructed_td == Timedelta(conversion)
|
||||
|
||||
|
||||
def test_td_constructor_value_error():
|
||||
with pytest.raises(TypeError):
|
||||
Timedelta(nanoseconds='abc')
|
||||
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
|
||||
from pandas import Timedelta
|
||||
|
||||
|
||||
@pytest.mark.parametrize('td, expected_repr', [
|
||||
(Timedelta(10, unit='d'), "Timedelta('10 days 00:00:00')"),
|
||||
(Timedelta(10, unit='s'), "Timedelta('0 days 00:00:10')"),
|
||||
(Timedelta(10, unit='ms'), "Timedelta('0 days 00:00:00.010000')"),
|
||||
(Timedelta(-10, unit='ms'), "Timedelta('-1 days +23:59:59.990000')")])
|
||||
def test_repr(td, expected_repr):
|
||||
assert repr(td) == expected_repr
|
||||
|
||||
|
||||
@pytest.mark.parametrize('td, expected_iso', [
|
||||
(Timedelta(days=6, minutes=50, seconds=3, milliseconds=10, microseconds=10,
|
||||
nanoseconds=12), 'P6DT0H50M3.010010012S'),
|
||||
(Timedelta(days=4, hours=12, minutes=30, seconds=5), 'P4DT12H30M5S'),
|
||||
(Timedelta(nanoseconds=123), 'P0DT0H0M0.000000123S'),
|
||||
# trim nano
|
||||
(Timedelta(microseconds=10), 'P0DT0H0M0.00001S'),
|
||||
# trim micro
|
||||
(Timedelta(milliseconds=1), 'P0DT0H0M0.001S'),
|
||||
# don't strip every 0
|
||||
(Timedelta(minutes=1), 'P0DT0H1M0S')])
|
||||
def test_isoformat(td, expected_iso):
|
||||
assert td.isoformat() == expected_iso
|
||||
+710
@@ -0,0 +1,710 @@
|
||||
""" test the scalar Timedelta """
|
||||
from datetime import timedelta
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas._libs.tslibs import NaT, iNaT
|
||||
import pandas.compat as compat
|
||||
|
||||
import pandas as pd
|
||||
from pandas import (
|
||||
Series, Timedelta, TimedeltaIndex, timedelta_range, to_timedelta)
|
||||
import pandas.util.testing as tm
|
||||
|
||||
|
||||
class TestTimedeltaArithmetic(object):
|
||||
|
||||
def test_arithmetic_overflow(self):
|
||||
with pytest.raises(OverflowError):
|
||||
pd.Timestamp('1700-01-01') + pd.Timedelta(13 * 19999, unit='D')
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
pd.Timestamp('1700-01-01') + timedelta(days=13 * 19999)
|
||||
|
||||
def test_array_timedelta_floordiv(self):
|
||||
# https://github.com/pandas-dev/pandas/issues/19761
|
||||
ints = pd.date_range('2012-10-08', periods=4, freq='D').view('i8')
|
||||
msg = r"Use 'array // timedelta.value'"
|
||||
with tm.assert_produces_warning(FutureWarning) as m:
|
||||
result = ints // pd.Timedelta(1, unit='s')
|
||||
|
||||
assert msg in str(m[0].message)
|
||||
expected = np.array([1349654400, 1349740800, 1349827200, 1349913600],
|
||||
dtype='i8')
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
def test_ops_error_str(self):
|
||||
# GH 13624
|
||||
td = Timedelta('1 day')
|
||||
|
||||
for left, right in [(td, 'a'), ('a', td)]:
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
left + right
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
left > right
|
||||
|
||||
assert not left == right
|
||||
assert left != right
|
||||
|
||||
def test_ops_notimplemented(self):
|
||||
class Other(object):
|
||||
pass
|
||||
|
||||
other = Other()
|
||||
|
||||
td = Timedelta('1 day')
|
||||
assert td.__add__(other) is NotImplemented
|
||||
assert td.__sub__(other) is NotImplemented
|
||||
assert td.__truediv__(other) is NotImplemented
|
||||
assert td.__mul__(other) is NotImplemented
|
||||
assert td.__floordiv__(other) is NotImplemented
|
||||
|
||||
def test_unary_ops(self):
|
||||
td = Timedelta(10, unit='d')
|
||||
|
||||
# __neg__, __pos__
|
||||
assert -td == Timedelta(-10, unit='d')
|
||||
assert -td == Timedelta('-10d')
|
||||
assert +td == Timedelta(10, unit='d')
|
||||
|
||||
# __abs__, __abs__(__neg__)
|
||||
assert abs(td) == td
|
||||
assert abs(-td) == td
|
||||
assert abs(-td) == Timedelta('10d')
|
||||
|
||||
|
||||
class TestTimedeltaComparison(object):
|
||||
def test_compare_tick(self, tick_classes):
|
||||
cls = tick_classes
|
||||
|
||||
off = cls(4)
|
||||
td = off.delta
|
||||
assert isinstance(td, Timedelta)
|
||||
|
||||
assert td == off
|
||||
assert not td != off
|
||||
assert td <= off
|
||||
assert td >= off
|
||||
assert not td < off
|
||||
assert not td > off
|
||||
|
||||
assert not td == 2 * off
|
||||
assert td != 2 * off
|
||||
assert td <= 2 * off
|
||||
assert td < 2 * off
|
||||
assert not td >= 2 * off
|
||||
assert not td > 2 * off
|
||||
|
||||
def test_comparison_object_array(self):
|
||||
# analogous to GH#15183
|
||||
td = Timedelta('2 days')
|
||||
other = Timedelta('3 hours')
|
||||
|
||||
arr = np.array([other, td], dtype=object)
|
||||
res = arr == td
|
||||
expected = np.array([False, True], dtype=bool)
|
||||
assert (res == expected).all()
|
||||
|
||||
# 2D case
|
||||
arr = np.array([[other, td],
|
||||
[td, other]],
|
||||
dtype=object)
|
||||
res = arr != td
|
||||
expected = np.array([[True, False], [False, True]], dtype=bool)
|
||||
assert res.shape == expected.shape
|
||||
assert (res == expected).all()
|
||||
|
||||
def test_compare_timedelta_ndarray(self):
|
||||
# GH11835
|
||||
periods = [Timedelta('0 days 01:00:00'), Timedelta('0 days 01:00:00')]
|
||||
arr = np.array(periods)
|
||||
result = arr[0] > arr
|
||||
expected = np.array([False, False])
|
||||
tm.assert_numpy_array_equal(result, expected)
|
||||
|
||||
@pytest.mark.skip(reason="GH#20829 is reverted until after 0.24.0")
|
||||
def test_compare_custom_object(self):
|
||||
"""
|
||||
Make sure non supported operations on Timedelta returns NonImplemented
|
||||
and yields to other operand (GH#20829).
|
||||
"""
|
||||
class CustomClass(object):
|
||||
|
||||
def __init__(self, cmp_result=None):
|
||||
self.cmp_result = cmp_result
|
||||
|
||||
def generic_result(self):
|
||||
if self.cmp_result is None:
|
||||
return NotImplemented
|
||||
else:
|
||||
return self.cmp_result
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.generic_result()
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.generic_result()
|
||||
|
||||
t = Timedelta('1s')
|
||||
|
||||
assert not (t == "string")
|
||||
assert not (t == 1)
|
||||
assert not (t == CustomClass())
|
||||
assert not (t == CustomClass(cmp_result=False))
|
||||
|
||||
assert t < CustomClass(cmp_result=True)
|
||||
assert not (t < CustomClass(cmp_result=False))
|
||||
|
||||
assert t == CustomClass(cmp_result=True)
|
||||
|
||||
@pytest.mark.parametrize("val", ["string", 1])
|
||||
def test_compare_unknown_type(self, val):
|
||||
# GH20829
|
||||
t = Timedelta('1s')
|
||||
with pytest.raises(TypeError):
|
||||
t >= val
|
||||
with pytest.raises(TypeError):
|
||||
t > val
|
||||
with pytest.raises(TypeError):
|
||||
t <= val
|
||||
with pytest.raises(TypeError):
|
||||
t < val
|
||||
|
||||
|
||||
class TestTimedeltas(object):
|
||||
|
||||
@pytest.mark.parametrize("unit, value, expected", [
|
||||
('us', 9.999, 9999), ('ms', 9.999999, 9999999),
|
||||
('s', 9.999999999, 9999999999)])
|
||||
def test_rounding_on_int_unit_construction(self, unit, value, expected):
|
||||
# GH 12690
|
||||
result = Timedelta(value, unit=unit)
|
||||
assert result.value == expected
|
||||
result = Timedelta(str(value) + unit)
|
||||
assert result.value == expected
|
||||
|
||||
def test_total_seconds_scalar(self):
|
||||
# see gh-10939
|
||||
rng = Timedelta('1 days, 10:11:12.100123456')
|
||||
expt = 1 * 86400 + 10 * 3600 + 11 * 60 + 12 + 100123456. / 1e9
|
||||
tm.assert_almost_equal(rng.total_seconds(), expt)
|
||||
|
||||
rng = Timedelta(np.nan)
|
||||
assert np.isnan(rng.total_seconds())
|
||||
|
||||
def test_conversion(self):
|
||||
|
||||
for td in [Timedelta(10, unit='d'),
|
||||
Timedelta('1 days, 10:11:12.012345')]:
|
||||
pydt = td.to_pytimedelta()
|
||||
assert td == Timedelta(pydt)
|
||||
assert td == pydt
|
||||
assert (isinstance(pydt, timedelta) and not isinstance(
|
||||
pydt, Timedelta))
|
||||
|
||||
assert td == np.timedelta64(td.value, 'ns')
|
||||
td64 = td.to_timedelta64()
|
||||
|
||||
assert td64 == np.timedelta64(td.value, 'ns')
|
||||
assert td == td64
|
||||
|
||||
assert isinstance(td64, np.timedelta64)
|
||||
|
||||
# this is NOT equal and cannot be roundtriped (because of the nanos)
|
||||
td = Timedelta('1 days, 10:11:12.012345678')
|
||||
assert td != td.to_pytimedelta()
|
||||
|
||||
def test_freq_conversion(self):
|
||||
|
||||
# truediv
|
||||
td = Timedelta('1 days 2 hours 3 ns')
|
||||
result = td / np.timedelta64(1, 'D')
|
||||
assert result == td.value / float(86400 * 1e9)
|
||||
result = td / np.timedelta64(1, 's')
|
||||
assert result == td.value / float(1e9)
|
||||
result = td / np.timedelta64(1, 'ns')
|
||||
assert result == td.value
|
||||
|
||||
# floordiv
|
||||
td = Timedelta('1 days 2 hours 3 ns')
|
||||
result = td // np.timedelta64(1, 'D')
|
||||
assert result == 1
|
||||
result = td // np.timedelta64(1, 's')
|
||||
assert result == 93600
|
||||
result = td // np.timedelta64(1, 'ns')
|
||||
assert result == td.value
|
||||
|
||||
def test_fields(self):
|
||||
def check(value):
|
||||
# that we are int/long like
|
||||
assert isinstance(value, (int, compat.long))
|
||||
|
||||
# compat to datetime.timedelta
|
||||
rng = to_timedelta('1 days, 10:11:12')
|
||||
assert rng.days == 1
|
||||
assert rng.seconds == 10 * 3600 + 11 * 60 + 12
|
||||
assert rng.microseconds == 0
|
||||
assert rng.nanoseconds == 0
|
||||
|
||||
pytest.raises(AttributeError, lambda: rng.hours)
|
||||
pytest.raises(AttributeError, lambda: rng.minutes)
|
||||
pytest.raises(AttributeError, lambda: rng.milliseconds)
|
||||
|
||||
# GH 10050
|
||||
check(rng.days)
|
||||
check(rng.seconds)
|
||||
check(rng.microseconds)
|
||||
check(rng.nanoseconds)
|
||||
|
||||
td = Timedelta('-1 days, 10:11:12')
|
||||
assert abs(td) == Timedelta('13:48:48')
|
||||
assert str(td) == "-1 days +10:11:12"
|
||||
assert -td == Timedelta('0 days 13:48:48')
|
||||
assert -Timedelta('-1 days, 10:11:12').value == 49728000000000
|
||||
assert Timedelta('-1 days, 10:11:12').value == -49728000000000
|
||||
|
||||
rng = to_timedelta('-1 days, 10:11:12.100123456')
|
||||
assert rng.days == -1
|
||||
assert rng.seconds == 10 * 3600 + 11 * 60 + 12
|
||||
assert rng.microseconds == 100 * 1000 + 123
|
||||
assert rng.nanoseconds == 456
|
||||
pytest.raises(AttributeError, lambda: rng.hours)
|
||||
pytest.raises(AttributeError, lambda: rng.minutes)
|
||||
pytest.raises(AttributeError, lambda: rng.milliseconds)
|
||||
|
||||
# components
|
||||
tup = pd.to_timedelta(-1, 'us').components
|
||||
assert tup.days == -1
|
||||
assert tup.hours == 23
|
||||
assert tup.minutes == 59
|
||||
assert tup.seconds == 59
|
||||
assert tup.milliseconds == 999
|
||||
assert tup.microseconds == 999
|
||||
assert tup.nanoseconds == 0
|
||||
|
||||
# GH 10050
|
||||
check(tup.days)
|
||||
check(tup.hours)
|
||||
check(tup.minutes)
|
||||
check(tup.seconds)
|
||||
check(tup.milliseconds)
|
||||
check(tup.microseconds)
|
||||
check(tup.nanoseconds)
|
||||
|
||||
tup = Timedelta('-1 days 1 us').components
|
||||
assert tup.days == -2
|
||||
assert tup.hours == 23
|
||||
assert tup.minutes == 59
|
||||
assert tup.seconds == 59
|
||||
assert tup.milliseconds == 999
|
||||
assert tup.microseconds == 999
|
||||
assert tup.nanoseconds == 0
|
||||
|
||||
def test_iso_conversion(self):
|
||||
# GH #21877
|
||||
expected = Timedelta(1, unit='s')
|
||||
assert to_timedelta('P0DT0H0M1S') == expected
|
||||
|
||||
def test_nat_converters(self):
|
||||
assert to_timedelta('nat', box=False).astype('int64') == iNaT
|
||||
assert to_timedelta('nan', box=False).astype('int64') == iNaT
|
||||
|
||||
@pytest.mark.parametrize('units, np_unit',
|
||||
[(['Y', 'y'], 'Y'),
|
||||
(['M'], 'M'),
|
||||
(['W', 'w'], 'W'),
|
||||
(['D', 'd', 'days', 'day', 'Days', 'Day'], 'D'),
|
||||
(['m', 'minute', 'min', 'minutes', 't',
|
||||
'Minute', 'Min', 'Minutes', 'T'], 'm'),
|
||||
(['s', 'seconds', 'sec', 'second',
|
||||
'S', 'Seconds', 'Sec', 'Second'], 's'),
|
||||
(['ms', 'milliseconds', 'millisecond', 'milli',
|
||||
'millis', 'l', 'MS', 'Milliseconds',
|
||||
'Millisecond', 'Milli', 'Millis', 'L'], 'ms'),
|
||||
(['us', 'microseconds', 'microsecond', 'micro',
|
||||
'micros', 'u', 'US', 'Microseconds',
|
||||
'Microsecond', 'Micro', 'Micros', 'U'], 'us'),
|
||||
(['ns', 'nanoseconds', 'nanosecond', 'nano',
|
||||
'nanos', 'n', 'NS', 'Nanoseconds',
|
||||
'Nanosecond', 'Nano', 'Nanos', 'N'], 'ns')])
|
||||
@pytest.mark.parametrize('wrapper', [np.array, list, pd.Index])
|
||||
def test_unit_parser(self, units, np_unit, wrapper):
|
||||
# validate all units, GH 6855, GH 21762
|
||||
for unit in units:
|
||||
# array-likes
|
||||
expected = TimedeltaIndex([np.timedelta64(i, np_unit)
|
||||
for i in np.arange(5).tolist()])
|
||||
result = to_timedelta(wrapper(range(5)), unit=unit)
|
||||
tm.assert_index_equal(result, expected)
|
||||
result = TimedeltaIndex(wrapper(range(5)), unit=unit)
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
if unit == 'M':
|
||||
# M is treated as minutes in string repr
|
||||
expected = TimedeltaIndex([np.timedelta64(i, 'm')
|
||||
for i in np.arange(5).tolist()])
|
||||
|
||||
str_repr = ['{}{}'.format(x, unit) for x in np.arange(5)]
|
||||
result = to_timedelta(wrapper(str_repr))
|
||||
tm.assert_index_equal(result, expected)
|
||||
result = TimedeltaIndex(wrapper(str_repr))
|
||||
tm.assert_index_equal(result, expected)
|
||||
|
||||
# scalar
|
||||
expected = Timedelta(np.timedelta64(2, np_unit).astype(
|
||||
'timedelta64[ns]'))
|
||||
|
||||
result = to_timedelta(2, unit=unit)
|
||||
assert result == expected
|
||||
result = Timedelta(2, unit=unit)
|
||||
assert result == expected
|
||||
|
||||
if unit == 'M':
|
||||
expected = Timedelta(np.timedelta64(2, 'm').astype(
|
||||
'timedelta64[ns]'))
|
||||
|
||||
result = to_timedelta('2{}'.format(unit))
|
||||
assert result == expected
|
||||
result = Timedelta('2{}'.format(unit))
|
||||
assert result == expected
|
||||
|
||||
def test_numeric_conversions(self):
|
||||
assert Timedelta(0) == np.timedelta64(0, 'ns')
|
||||
assert Timedelta(10) == np.timedelta64(10, 'ns')
|
||||
assert Timedelta(10, unit='ns') == np.timedelta64(10, 'ns')
|
||||
|
||||
assert Timedelta(10, unit='us') == np.timedelta64(10, 'us')
|
||||
assert Timedelta(10, unit='ms') == np.timedelta64(10, 'ms')
|
||||
assert Timedelta(10, unit='s') == np.timedelta64(10, 's')
|
||||
assert Timedelta(10, unit='d') == np.timedelta64(10, 'D')
|
||||
|
||||
def test_timedelta_conversions(self):
|
||||
assert (Timedelta(timedelta(seconds=1)) ==
|
||||
np.timedelta64(1, 's').astype('m8[ns]'))
|
||||
assert (Timedelta(timedelta(microseconds=1)) ==
|
||||
np.timedelta64(1, 'us').astype('m8[ns]'))
|
||||
assert (Timedelta(timedelta(days=1)) ==
|
||||
np.timedelta64(1, 'D').astype('m8[ns]'))
|
||||
|
||||
def test_round(self):
|
||||
|
||||
t1 = Timedelta('1 days 02:34:56.789123456')
|
||||
t2 = Timedelta('-1 days 02:34:56.789123456')
|
||||
|
||||
for (freq, s1, s2) in [('N', t1, t2),
|
||||
('U', Timedelta('1 days 02:34:56.789123000'),
|
||||
Timedelta('-1 days 02:34:56.789123000')),
|
||||
('L', Timedelta('1 days 02:34:56.789000000'),
|
||||
Timedelta('-1 days 02:34:56.789000000')),
|
||||
('S', Timedelta('1 days 02:34:57'),
|
||||
Timedelta('-1 days 02:34:57')),
|
||||
('2S', Timedelta('1 days 02:34:56'),
|
||||
Timedelta('-1 days 02:34:56')),
|
||||
('5S', Timedelta('1 days 02:34:55'),
|
||||
Timedelta('-1 days 02:34:55')),
|
||||
('T', Timedelta('1 days 02:35:00'),
|
||||
Timedelta('-1 days 02:35:00')),
|
||||
('12T', Timedelta('1 days 02:36:00'),
|
||||
Timedelta('-1 days 02:36:00')),
|
||||
('H', Timedelta('1 days 03:00:00'),
|
||||
Timedelta('-1 days 03:00:00')),
|
||||
('d', Timedelta('1 days'),
|
||||
Timedelta('-1 days'))]:
|
||||
r1 = t1.round(freq)
|
||||
assert r1 == s1
|
||||
r2 = t2.round(freq)
|
||||
assert r2 == s2
|
||||
|
||||
# invalid
|
||||
for freq in ['Y', 'M', 'foobar']:
|
||||
pytest.raises(ValueError, lambda: t1.round(freq))
|
||||
|
||||
t1 = timedelta_range('1 days', periods=3, freq='1 min 2 s 3 us')
|
||||
t2 = -1 * t1
|
||||
t1a = timedelta_range('1 days', periods=3, freq='1 min 2 s')
|
||||
t1c = pd.TimedeltaIndex([1, 1, 1], unit='D')
|
||||
|
||||
# note that negative times round DOWN! so don't give whole numbers
|
||||
for (freq, s1, s2) in [('N', t1, t2),
|
||||
('U', t1, t2),
|
||||
('L', t1a,
|
||||
TimedeltaIndex(['-1 days +00:00:00',
|
||||
'-2 days +23:58:58',
|
||||
'-2 days +23:57:56'],
|
||||
dtype='timedelta64[ns]',
|
||||
freq=None)
|
||||
),
|
||||
('S', t1a,
|
||||
TimedeltaIndex(['-1 days +00:00:00',
|
||||
'-2 days +23:58:58',
|
||||
'-2 days +23:57:56'],
|
||||
dtype='timedelta64[ns]',
|
||||
freq=None)
|
||||
),
|
||||
('12T', t1c,
|
||||
TimedeltaIndex(['-1 days',
|
||||
'-1 days',
|
||||
'-1 days'],
|
||||
dtype='timedelta64[ns]',
|
||||
freq=None)
|
||||
),
|
||||
('H', t1c,
|
||||
TimedeltaIndex(['-1 days',
|
||||
'-1 days',
|
||||
'-1 days'],
|
||||
dtype='timedelta64[ns]',
|
||||
freq=None)
|
||||
),
|
||||
('d', t1c,
|
||||
pd.TimedeltaIndex([-1, -1, -1], unit='D')
|
||||
)]:
|
||||
|
||||
r1 = t1.round(freq)
|
||||
tm.assert_index_equal(r1, s1)
|
||||
r2 = t2.round(freq)
|
||||
tm.assert_index_equal(r2, s2)
|
||||
|
||||
# invalid
|
||||
for freq in ['Y', 'M', 'foobar']:
|
||||
pytest.raises(ValueError, lambda: t1.round(freq))
|
||||
|
||||
def test_contains(self):
|
||||
# Checking for any NaT-like objects
|
||||
# GH 13603
|
||||
td = to_timedelta(range(5), unit='d') + pd.offsets.Hour(1)
|
||||
for v in [pd.NaT, None, float('nan'), np.nan]:
|
||||
assert not (v in td)
|
||||
|
||||
td = to_timedelta([pd.NaT])
|
||||
for v in [pd.NaT, None, float('nan'), np.nan]:
|
||||
assert (v in td)
|
||||
|
||||
def test_identity(self):
|
||||
|
||||
td = Timedelta(10, unit='d')
|
||||
assert isinstance(td, Timedelta)
|
||||
assert isinstance(td, timedelta)
|
||||
|
||||
def test_short_format_converters(self):
|
||||
def conv(v):
|
||||
return v.astype('m8[ns]')
|
||||
|
||||
assert Timedelta('10') == np.timedelta64(10, 'ns')
|
||||
assert Timedelta('10ns') == np.timedelta64(10, 'ns')
|
||||
assert Timedelta('100') == np.timedelta64(100, 'ns')
|
||||
assert Timedelta('100ns') == np.timedelta64(100, 'ns')
|
||||
|
||||
assert Timedelta('1000') == np.timedelta64(1000, 'ns')
|
||||
assert Timedelta('1000ns') == np.timedelta64(1000, 'ns')
|
||||
assert Timedelta('1000NS') == np.timedelta64(1000, 'ns')
|
||||
|
||||
assert Timedelta('10us') == np.timedelta64(10000, 'ns')
|
||||
assert Timedelta('100us') == np.timedelta64(100000, 'ns')
|
||||
assert Timedelta('1000us') == np.timedelta64(1000000, 'ns')
|
||||
assert Timedelta('1000Us') == np.timedelta64(1000000, 'ns')
|
||||
assert Timedelta('1000uS') == np.timedelta64(1000000, 'ns')
|
||||
|
||||
assert Timedelta('1ms') == np.timedelta64(1000000, 'ns')
|
||||
assert Timedelta('10ms') == np.timedelta64(10000000, 'ns')
|
||||
assert Timedelta('100ms') == np.timedelta64(100000000, 'ns')
|
||||
assert Timedelta('1000ms') == np.timedelta64(1000000000, 'ns')
|
||||
|
||||
assert Timedelta('-1s') == -np.timedelta64(1000000000, 'ns')
|
||||
assert Timedelta('1s') == np.timedelta64(1000000000, 'ns')
|
||||
assert Timedelta('10s') == np.timedelta64(10000000000, 'ns')
|
||||
assert Timedelta('100s') == np.timedelta64(100000000000, 'ns')
|
||||
assert Timedelta('1000s') == np.timedelta64(1000000000000, 'ns')
|
||||
|
||||
assert Timedelta('1d') == conv(np.timedelta64(1, 'D'))
|
||||
assert Timedelta('-1d') == -conv(np.timedelta64(1, 'D'))
|
||||
assert Timedelta('1D') == conv(np.timedelta64(1, 'D'))
|
||||
assert Timedelta('10D') == conv(np.timedelta64(10, 'D'))
|
||||
assert Timedelta('100D') == conv(np.timedelta64(100, 'D'))
|
||||
assert Timedelta('1000D') == conv(np.timedelta64(1000, 'D'))
|
||||
assert Timedelta('10000D') == conv(np.timedelta64(10000, 'D'))
|
||||
|
||||
# space
|
||||
assert Timedelta(' 10000D ') == conv(np.timedelta64(10000, 'D'))
|
||||
assert Timedelta(' - 10000D ') == -conv(np.timedelta64(10000, 'D'))
|
||||
|
||||
# invalid
|
||||
with pytest.raises(ValueError):
|
||||
Timedelta('1foo')
|
||||
with pytest.raises(ValueError):
|
||||
Timedelta('foo')
|
||||
|
||||
def test_full_format_converters(self):
|
||||
def conv(v):
|
||||
return v.astype('m8[ns]')
|
||||
|
||||
d1 = np.timedelta64(1, 'D')
|
||||
|
||||
assert Timedelta('1days') == conv(d1)
|
||||
assert Timedelta('1days,') == conv(d1)
|
||||
assert Timedelta('- 1days,') == -conv(d1)
|
||||
|
||||
assert Timedelta('00:00:01') == conv(np.timedelta64(1, 's'))
|
||||
assert Timedelta('06:00:01') == conv(np.timedelta64(6 * 3600 + 1, 's'))
|
||||
assert Timedelta('06:00:01.0') == conv(
|
||||
np.timedelta64(6 * 3600 + 1, 's'))
|
||||
assert Timedelta('06:00:01.01') == conv(np.timedelta64(
|
||||
1000 * (6 * 3600 + 1) + 10, 'ms'))
|
||||
|
||||
assert (Timedelta('- 1days, 00:00:01') ==
|
||||
conv(-d1 + np.timedelta64(1, 's')))
|
||||
assert (Timedelta('1days, 06:00:01') ==
|
||||
conv(d1 + np.timedelta64(6 * 3600 + 1, 's')))
|
||||
assert (Timedelta('1days, 06:00:01.01') ==
|
||||
conv(d1 + np.timedelta64(1000 * (6 * 3600 + 1) + 10, 'ms')))
|
||||
|
||||
# invalid
|
||||
with pytest.raises(ValueError):
|
||||
Timedelta('- 1days, 00')
|
||||
|
||||
def test_overflow(self):
|
||||
# GH 9442
|
||||
s = Series(pd.date_range('20130101', periods=100000, freq='H'))
|
||||
s[0] += pd.Timedelta('1s 1ms')
|
||||
|
||||
# mean
|
||||
result = (s - s.min()).mean()
|
||||
expected = pd.Timedelta((pd.TimedeltaIndex((s - s.min())).asi8 / len(s)
|
||||
).sum())
|
||||
|
||||
# the computation is converted to float so
|
||||
# might be some loss of precision
|
||||
assert np.allclose(result.value / 1000, expected.value / 1000)
|
||||
|
||||
# sum
|
||||
pytest.raises(ValueError, lambda: (s - s.min()).sum())
|
||||
s1 = s[0:10000]
|
||||
pytest.raises(ValueError, lambda: (s1 - s1.min()).sum())
|
||||
s2 = s[0:1000]
|
||||
result = (s2 - s2.min()).sum()
|
||||
|
||||
def test_pickle(self):
|
||||
|
||||
v = Timedelta('1 days 10:11:12.0123456')
|
||||
v_p = tm.round_trip_pickle(v)
|
||||
assert v == v_p
|
||||
|
||||
def test_timedelta_hash_equality(self):
|
||||
# GH 11129
|
||||
v = Timedelta(1, 'D')
|
||||
td = timedelta(days=1)
|
||||
assert hash(v) == hash(td)
|
||||
|
||||
d = {td: 2}
|
||||
assert d[v] == 2
|
||||
|
||||
tds = timedelta_range('1 second', periods=20)
|
||||
assert all(hash(td) == hash(td.to_pytimedelta()) for td in tds)
|
||||
|
||||
# python timedeltas drop ns resolution
|
||||
ns_td = Timedelta(1, 'ns')
|
||||
assert hash(ns_td) != hash(ns_td.to_pytimedelta())
|
||||
|
||||
def test_implementation_limits(self):
|
||||
min_td = Timedelta(Timedelta.min)
|
||||
max_td = Timedelta(Timedelta.max)
|
||||
|
||||
# GH 12727
|
||||
# timedelta limits correspond to int64 boundaries
|
||||
assert min_td.value == np.iinfo(np.int64).min + 1
|
||||
assert max_td.value == np.iinfo(np.int64).max
|
||||
|
||||
# Beyond lower limit, a NAT before the Overflow
|
||||
assert (min_td - Timedelta(1, 'ns')) is NaT
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
min_td - Timedelta(2, 'ns')
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
max_td + Timedelta(1, 'ns')
|
||||
|
||||
# Same tests using the internal nanosecond values
|
||||
td = Timedelta(min_td.value - 1, 'ns')
|
||||
assert td is NaT
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
Timedelta(min_td.value - 2, 'ns')
|
||||
|
||||
with pytest.raises(OverflowError):
|
||||
Timedelta(max_td.value + 1, 'ns')
|
||||
|
||||
def test_total_seconds_precision(self):
|
||||
# GH 19458
|
||||
assert Timedelta('30S').total_seconds() == 30.0
|
||||
assert Timedelta('0').total_seconds() == 0.0
|
||||
assert Timedelta('-2S').total_seconds() == -2.0
|
||||
assert Timedelta('5.324S').total_seconds() == 5.324
|
||||
assert (Timedelta('30S').total_seconds() - 30.0) < 1e-20
|
||||
assert (30.0 - Timedelta('30S').total_seconds()) < 1e-20
|
||||
|
||||
def test_timedelta_arithmetic(self):
|
||||
data = pd.Series(['nat', '32 days'], dtype='timedelta64[ns]')
|
||||
deltas = [timedelta(days=1), Timedelta(1, unit='D')]
|
||||
for delta in deltas:
|
||||
result_method = data.add(delta)
|
||||
result_operator = data + delta
|
||||
expected = pd.Series(['nat', '33 days'], dtype='timedelta64[ns]')
|
||||
tm.assert_series_equal(result_operator, expected)
|
||||
tm.assert_series_equal(result_method, expected)
|
||||
|
||||
result_method = data.sub(delta)
|
||||
result_operator = data - delta
|
||||
expected = pd.Series(['nat', '31 days'], dtype='timedelta64[ns]')
|
||||
tm.assert_series_equal(result_operator, expected)
|
||||
tm.assert_series_equal(result_method, expected)
|
||||
# GH 9396
|
||||
result_method = data.div(delta)
|
||||
result_operator = data / delta
|
||||
expected = pd.Series([np.nan, 32.], dtype='float64')
|
||||
tm.assert_series_equal(result_operator, expected)
|
||||
tm.assert_series_equal(result_method, expected)
|
||||
|
||||
def test_apply_to_timedelta(self):
|
||||
timedelta_NaT = pd.to_timedelta('NaT')
|
||||
|
||||
list_of_valid_strings = ['00:00:01', '00:00:02']
|
||||
a = pd.to_timedelta(list_of_valid_strings)
|
||||
b = Series(list_of_valid_strings).apply(pd.to_timedelta)
|
||||
# Can't compare until apply on a Series gives the correct dtype
|
||||
# assert_series_equal(a, b)
|
||||
|
||||
list_of_strings = ['00:00:01', np.nan, pd.NaT, timedelta_NaT]
|
||||
|
||||
# TODO: unused?
|
||||
a = pd.to_timedelta(list_of_strings) # noqa
|
||||
b = Series(list_of_strings).apply(pd.to_timedelta) # noqa
|
||||
# Can't compare until apply on a Series gives the correct dtype
|
||||
# assert_series_equal(a, b)
|
||||
|
||||
def test_components(self):
|
||||
rng = timedelta_range('1 days, 10:11:12', periods=2, freq='s')
|
||||
rng.components
|
||||
|
||||
# with nat
|
||||
s = Series(rng)
|
||||
s[1] = np.nan
|
||||
|
||||
result = s.dt.components
|
||||
assert not result.iloc[0].isna().all()
|
||||
assert result.iloc[1].isna().all()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value, expected', [
|
||||
(Timedelta('10S'), True),
|
||||
(Timedelta('-10S'), True),
|
||||
(Timedelta(10, unit='ns'), True),
|
||||
(Timedelta(0, unit='ns'), False),
|
||||
(Timedelta(-10, unit='ns'), True),
|
||||
(Timedelta(None), True),
|
||||
(pd.NaT, True),
|
||||
])
|
||||
def test_truthiness(value, expected):
|
||||
# https://github.com/pandas-dev/pandas/issues/21484
|
||||
assert bool(value) is expected
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+117
@@ -0,0 +1,117 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas.compat import long
|
||||
|
||||
from pandas import Timedelta, Timestamp
|
||||
import pandas.util.testing as tm
|
||||
|
||||
from pandas.tseries import offsets
|
||||
from pandas.tseries.frequencies import to_offset
|
||||
|
||||
|
||||
class TestTimestampArithmetic(object):
|
||||
def test_overflow_offset(self):
|
||||
# no overflow expected
|
||||
|
||||
stamp = Timestamp("2000/1/1")
|
||||
offset_no_overflow = to_offset("D") * 100
|
||||
|
||||
expected = Timestamp("2000/04/10")
|
||||
assert stamp + offset_no_overflow == expected
|
||||
|
||||
assert offset_no_overflow + stamp == expected
|
||||
|
||||
expected = Timestamp("1999/09/23")
|
||||
assert stamp - offset_no_overflow == expected
|
||||
|
||||
def test_overflow_offset_raises(self):
|
||||
# xref https://github.com/statsmodels/statsmodels/issues/3374
|
||||
# ends up multiplying really large numbers which overflow
|
||||
|
||||
stamp = Timestamp('2017-01-13 00:00:00', freq='D')
|
||||
offset_overflow = 20169940 * offsets.Day(1)
|
||||
msg = ("the add operation between "
|
||||
r"\<-?\d+ \* Days\> and \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} "
|
||||
"will overflow")
|
||||
|
||||
with pytest.raises(OverflowError, match=msg):
|
||||
stamp + offset_overflow
|
||||
|
||||
with pytest.raises(OverflowError, match=msg):
|
||||
offset_overflow + stamp
|
||||
|
||||
with pytest.raises(OverflowError, match=msg):
|
||||
stamp - offset_overflow
|
||||
|
||||
# xref https://github.com/pandas-dev/pandas/issues/14080
|
||||
# used to crash, so check for proper overflow exception
|
||||
|
||||
stamp = Timestamp("2000/1/1")
|
||||
offset_overflow = to_offset("D") * 100 ** 25
|
||||
|
||||
with pytest.raises(OverflowError, match=msg):
|
||||
stamp + offset_overflow
|
||||
|
||||
with pytest.raises(OverflowError, match=msg):
|
||||
offset_overflow + stamp
|
||||
|
||||
with pytest.raises(OverflowError, match=msg):
|
||||
stamp - offset_overflow
|
||||
|
||||
def test_delta_preserve_nanos(self):
|
||||
val = Timestamp(long(1337299200000000123))
|
||||
result = val + timedelta(1)
|
||||
assert result.nanosecond == val.nanosecond
|
||||
|
||||
def test_timestamp_sub_datetime(self):
|
||||
dt = datetime(2013, 10, 12)
|
||||
ts = Timestamp(datetime(2013, 10, 13))
|
||||
assert (ts - dt).days == 1
|
||||
assert (dt - ts).days == -1
|
||||
|
||||
def test_addition_subtraction_types(self):
|
||||
# Assert on the types resulting from Timestamp +/- various date/time
|
||||
# objects
|
||||
dt = datetime(2014, 3, 4)
|
||||
td = timedelta(seconds=1)
|
||||
# build a timestamp with a frequency, since then it supports
|
||||
# addition/subtraction of integers
|
||||
ts = Timestamp(dt, freq='D')
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# GH#22535 add/sub with integers is deprecated
|
||||
assert type(ts + 1) == Timestamp
|
||||
assert type(ts - 1) == Timestamp
|
||||
|
||||
# Timestamp + datetime not supported, though subtraction is supported
|
||||
# and yields timedelta more tests in tseries/base/tests/test_base.py
|
||||
assert type(ts - dt) == Timedelta
|
||||
assert type(ts + td) == Timestamp
|
||||
assert type(ts - td) == Timestamp
|
||||
|
||||
# Timestamp +/- datetime64 not supported, so not tested (could possibly
|
||||
# assert error raised?)
|
||||
td64 = np.timedelta64(1, 'D')
|
||||
assert type(ts + td64) == Timestamp
|
||||
assert type(ts - td64) == Timestamp
|
||||
|
||||
def test_addition_subtraction_preserve_frequency(self):
|
||||
ts = Timestamp('2014-03-05', freq='D')
|
||||
td = timedelta(days=1)
|
||||
original_freq = ts.freq
|
||||
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
# GH#22535 add/sub with integers is deprecated
|
||||
assert (ts + 1).freq == original_freq
|
||||
assert (ts - 1).freq == original_freq
|
||||
|
||||
assert (ts + td).freq == original_freq
|
||||
assert (ts - td).freq == original_freq
|
||||
|
||||
td64 = np.timedelta64(1, 'D')
|
||||
assert (ts + td64).freq == original_freq
|
||||
assert (ts - td64).freq == original_freq
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime
|
||||
import operator
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pandas.compat import PY2, long
|
||||
|
||||
from pandas import Timestamp
|
||||
|
||||
|
||||
class TestTimestampComparison(object):
|
||||
def test_comparison_object_array(self):
|
||||
# GH#15183
|
||||
ts = Timestamp('2011-01-03 00:00:00-0500', tz='US/Eastern')
|
||||
other = Timestamp('2011-01-01 00:00:00-0500', tz='US/Eastern')
|
||||
naive = Timestamp('2011-01-01 00:00:00')
|
||||
|
||||
arr = np.array([other, ts], dtype=object)
|
||||
res = arr == ts
|
||||
expected = np.array([False, True], dtype=bool)
|
||||
assert (res == expected).all()
|
||||
|
||||
# 2D case
|
||||
arr = np.array([[other, ts],
|
||||
[ts, other]],
|
||||
dtype=object)
|
||||
res = arr != ts
|
||||
expected = np.array([[True, False], [False, True]], dtype=bool)
|
||||
assert res.shape == expected.shape
|
||||
assert (res == expected).all()
|
||||
|
||||
# tzaware mismatch
|
||||
arr = np.array([naive], dtype=object)
|
||||
with pytest.raises(TypeError):
|
||||
arr < ts
|
||||
|
||||
def test_comparison(self):
|
||||
# 5-18-2012 00:00:00.000
|
||||
stamp = long(1337299200000000000)
|
||||
|
||||
val = Timestamp(stamp)
|
||||
|
||||
assert val == val
|
||||
assert not val != val
|
||||
assert not val < val
|
||||
assert val <= val
|
||||
assert not val > val
|
||||
assert val >= val
|
||||
|
||||
other = datetime(2012, 5, 18)
|
||||
assert val == other
|
||||
assert not val != other
|
||||
assert not val < other
|
||||
assert val <= other
|
||||
assert not val > other
|
||||
assert val >= other
|
||||
|
||||
other = Timestamp(stamp + 100)
|
||||
|
||||
assert val != other
|
||||
assert val != other
|
||||
assert val < other
|
||||
assert val <= other
|
||||
assert other > val
|
||||
assert other >= val
|
||||
|
||||
def test_compare_invalid(self):
|
||||
# GH#8058
|
||||
val = Timestamp('20130101 12:01:02')
|
||||
assert not val == 'foo'
|
||||
assert not val == 10.0
|
||||
assert not val == 1
|
||||
assert not val == long(1)
|
||||
assert not val == []
|
||||
assert not val == {'foo': 1}
|
||||
assert not val == np.float64(1)
|
||||
assert not val == np.int64(1)
|
||||
|
||||
assert val != 'foo'
|
||||
assert val != 10.0
|
||||
assert val != 1
|
||||
assert val != long(1)
|
||||
assert val != []
|
||||
assert val != {'foo': 1}
|
||||
assert val != np.float64(1)
|
||||
assert val != np.int64(1)
|
||||
|
||||
def test_cant_compare_tz_naive_w_aware(self, utc_fixture):
|
||||
# see GH#1404
|
||||
a = Timestamp('3/12/2012')
|
||||
b = Timestamp('3/12/2012', tz=utc_fixture)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
a == b
|
||||
with pytest.raises(TypeError):
|
||||
a != b
|
||||
with pytest.raises(TypeError):
|
||||
a < b
|
||||
with pytest.raises(TypeError):
|
||||
a <= b
|
||||
with pytest.raises(TypeError):
|
||||
a > b
|
||||
with pytest.raises(TypeError):
|
||||
a >= b
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
b == a
|
||||
with pytest.raises(TypeError):
|
||||
b != a
|
||||
with pytest.raises(TypeError):
|
||||
b < a
|
||||
with pytest.raises(TypeError):
|
||||
b <= a
|
||||
with pytest.raises(TypeError):
|
||||
b > a
|
||||
with pytest.raises(TypeError):
|
||||
b >= a
|
||||
|
||||
if PY2:
|
||||
with pytest.raises(TypeError):
|
||||
a == b.to_pydatetime()
|
||||
with pytest.raises(TypeError):
|
||||
a.to_pydatetime() == b
|
||||
else:
|
||||
assert not a == b.to_pydatetime()
|
||||
assert not a.to_pydatetime() == b
|
||||
|
||||
def test_timestamp_compare_scalars(self):
|
||||
# case where ndim == 0
|
||||
lhs = np.datetime64(datetime(2013, 12, 6))
|
||||
rhs = Timestamp('now')
|
||||
nat = Timestamp('nat')
|
||||
|
||||
ops = {'gt': 'lt',
|
||||
'lt': 'gt',
|
||||
'ge': 'le',
|
||||
'le': 'ge',
|
||||
'eq': 'eq',
|
||||
'ne': 'ne'}
|
||||
|
||||
for left, right in ops.items():
|
||||
left_f = getattr(operator, left)
|
||||
right_f = getattr(operator, right)
|
||||
expected = left_f(lhs, rhs)
|
||||
|
||||
result = right_f(rhs, lhs)
|
||||
assert result == expected
|
||||
|
||||
expected = left_f(rhs, nat)
|
||||
result = right_f(nat, rhs)
|
||||
assert result == expected
|
||||
|
||||
def test_timestamp_compare_with_early_datetime(self):
|
||||
# e.g. datetime.min
|
||||
stamp = Timestamp('2012-01-01')
|
||||
|
||||
assert not stamp == datetime.min
|
||||
assert not stamp == datetime(1600, 1, 1)
|
||||
assert not stamp == datetime(2700, 1, 1)
|
||||
assert stamp != datetime.min
|
||||
assert stamp != datetime(1600, 1, 1)
|
||||
assert stamp != datetime(2700, 1, 1)
|
||||
assert stamp > datetime(1600, 1, 1)
|
||||
assert stamp >= datetime(1600, 1, 1)
|
||||
assert stamp < datetime(2700, 1, 1)
|
||||
assert stamp <= datetime(2700, 1, 1)
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
import pprint
|
||||
|
||||
import dateutil
|
||||
import pytest
|
||||
import pytz # noqa # a test below uses pytz but only inside a `eval` call
|
||||
|
||||
from pandas import Timestamp
|
||||
|
||||
|
||||
class TestTimestampRendering(object):
|
||||
|
||||
# dateutil zone change (only matters for repr)
|
||||
if LooseVersion(dateutil.__version__) >= LooseVersion('2.6.0'):
|
||||
timezones = ['UTC', 'Asia/Tokyo', 'US/Eastern',
|
||||
'dateutil/US/Pacific']
|
||||
else:
|
||||
timezones = ['UTC', 'Asia/Tokyo', 'US/Eastern',
|
||||
'dateutil/America/Los_Angeles']
|
||||
|
||||
@pytest.mark.parametrize('tz', timezones)
|
||||
@pytest.mark.parametrize('freq', ['D', 'M', 'S', 'N'])
|
||||
@pytest.mark.parametrize('date', ['2014-03-07', '2014-01-01 09:00',
|
||||
'2014-01-01 00:00:00.000000001'])
|
||||
def test_repr(self, date, freq, tz):
|
||||
# avoid to match with timezone name
|
||||
freq_repr = "'{0}'".format(freq)
|
||||
if tz.startswith('dateutil'):
|
||||
tz_repr = tz.replace('dateutil', '')
|
||||
else:
|
||||
tz_repr = tz
|
||||
|
||||
date_only = Timestamp(date)
|
||||
assert date in repr(date_only)
|
||||
assert tz_repr not in repr(date_only)
|
||||
assert freq_repr not in repr(date_only)
|
||||
assert date_only == eval(repr(date_only))
|
||||
|
||||
date_tz = Timestamp(date, tz=tz)
|
||||
assert date in repr(date_tz)
|
||||
assert tz_repr in repr(date_tz)
|
||||
assert freq_repr not in repr(date_tz)
|
||||
assert date_tz == eval(repr(date_tz))
|
||||
|
||||
date_freq = Timestamp(date, freq=freq)
|
||||
assert date in repr(date_freq)
|
||||
assert tz_repr not in repr(date_freq)
|
||||
assert freq_repr in repr(date_freq)
|
||||
assert date_freq == eval(repr(date_freq))
|
||||
|
||||
date_tz_freq = Timestamp(date, tz=tz, freq=freq)
|
||||
assert date in repr(date_tz_freq)
|
||||
assert tz_repr in repr(date_tz_freq)
|
||||
assert freq_repr in repr(date_tz_freq)
|
||||
assert date_tz_freq == eval(repr(date_tz_freq))
|
||||
|
||||
def test_repr_utcoffset(self):
|
||||
# This can cause the tz field to be populated, but it's redundant to
|
||||
# include this information in the date-string.
|
||||
date_with_utc_offset = Timestamp('2014-03-13 00:00:00-0400', tz=None)
|
||||
assert '2014-03-13 00:00:00-0400' in repr(date_with_utc_offset)
|
||||
assert 'tzoffset' not in repr(date_with_utc_offset)
|
||||
assert 'pytz.FixedOffset(-240)' in repr(date_with_utc_offset)
|
||||
expr = repr(date_with_utc_offset).replace("'pytz.FixedOffset(-240)'",
|
||||
'pytz.FixedOffset(-240)')
|
||||
assert date_with_utc_offset == eval(expr)
|
||||
|
||||
def test_timestamp_repr_pre1900(self):
|
||||
# pre-1900
|
||||
stamp = Timestamp('1850-01-01', tz='US/Eastern')
|
||||
repr(stamp)
|
||||
|
||||
iso8601 = '1850-01-01 01:23:45.012345'
|
||||
stamp = Timestamp(iso8601, tz='US/Eastern')
|
||||
result = repr(stamp)
|
||||
assert iso8601 in result
|
||||
|
||||
def test_pprint(self):
|
||||
# GH#12622
|
||||
nested_obj = {'foo': 1,
|
||||
'bar': [{'w': {'a': Timestamp('2011-01-01')}}] * 10}
|
||||
result = pprint.pformat(nested_obj, width=50)
|
||||
expected = r"""{'bar': [{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}},
|
||||
{'w': {'a': Timestamp('2011-01-01 00:00:00')}}],
|
||||
'foo': 1}"""
|
||||
assert result == expected
|
||||
+964
@@ -0,0 +1,964 @@
|
||||
""" test the scalar Timestamp """
|
||||
|
||||
import calendar
|
||||
from datetime import datetime, timedelta
|
||||
import locale
|
||||
import unicodedata
|
||||
|
||||
import dateutil
|
||||
from dateutil.tz import tzutc
|
||||
import numpy as np
|
||||
import pytest
|
||||
import pytz
|
||||
from pytz import timezone, utc
|
||||
|
||||
from pandas._libs.tslibs import conversion
|
||||
from pandas._libs.tslibs.timezones import dateutil_gettz as gettz, get_timezone
|
||||
from pandas.compat import PY2, PY3, long
|
||||
from pandas.compat.numpy import np_datetime64_compat
|
||||
from pandas.errors import OutOfBoundsDatetime
|
||||
import pandas.util._test_decorators as td
|
||||
|
||||
from pandas import NaT, Period, Timedelta, Timestamp
|
||||
import pandas.util.testing as tm
|
||||
|
||||
from pandas.tseries import offsets
|
||||
|
||||
|
||||
class TestTimestampProperties(object):
|
||||
|
||||
def test_properties_business(self):
|
||||
ts = Timestamp('2017-10-01', freq='B')
|
||||
control = Timestamp('2017-10-01')
|
||||
assert ts.dayofweek == 6
|
||||
assert not ts.is_month_start # not a weekday
|
||||
assert not ts.is_quarter_start # not a weekday
|
||||
# Control case: non-business is month/qtr start
|
||||
assert control.is_month_start
|
||||
assert control.is_quarter_start
|
||||
|
||||
ts = Timestamp('2017-09-30', freq='B')
|
||||
control = Timestamp('2017-09-30')
|
||||
assert ts.dayofweek == 5
|
||||
assert not ts.is_month_end # not a weekday
|
||||
assert not ts.is_quarter_end # not a weekday
|
||||
# Control case: non-business is month/qtr start
|
||||
assert control.is_month_end
|
||||
assert control.is_quarter_end
|
||||
|
||||
def test_fields(self):
|
||||
def check(value, equal):
|
||||
# that we are int/long like
|
||||
assert isinstance(value, (int, long))
|
||||
assert value == equal
|
||||
|
||||
# GH 10050
|
||||
ts = Timestamp('2015-05-10 09:06:03.000100001')
|
||||
check(ts.year, 2015)
|
||||
check(ts.month, 5)
|
||||
check(ts.day, 10)
|
||||
check(ts.hour, 9)
|
||||
check(ts.minute, 6)
|
||||
check(ts.second, 3)
|
||||
pytest.raises(AttributeError, lambda: ts.millisecond)
|
||||
check(ts.microsecond, 100)
|
||||
check(ts.nanosecond, 1)
|
||||
check(ts.dayofweek, 6)
|
||||
check(ts.quarter, 2)
|
||||
check(ts.dayofyear, 130)
|
||||
check(ts.week, 19)
|
||||
check(ts.daysinmonth, 31)
|
||||
check(ts.daysinmonth, 31)
|
||||
|
||||
# GH 13303
|
||||
ts = Timestamp('2014-12-31 23:59:00-05:00', tz='US/Eastern')
|
||||
check(ts.year, 2014)
|
||||
check(ts.month, 12)
|
||||
check(ts.day, 31)
|
||||
check(ts.hour, 23)
|
||||
check(ts.minute, 59)
|
||||
check(ts.second, 0)
|
||||
pytest.raises(AttributeError, lambda: ts.millisecond)
|
||||
check(ts.microsecond, 0)
|
||||
check(ts.nanosecond, 0)
|
||||
check(ts.dayofweek, 2)
|
||||
check(ts.quarter, 4)
|
||||
check(ts.dayofyear, 365)
|
||||
check(ts.week, 1)
|
||||
check(ts.daysinmonth, 31)
|
||||
|
||||
ts = Timestamp('2014-01-01 00:00:00+01:00')
|
||||
starts = ['is_month_start', 'is_quarter_start', 'is_year_start']
|
||||
for start in starts:
|
||||
assert getattr(ts, start)
|
||||
ts = Timestamp('2014-12-31 23:59:59+01:00')
|
||||
ends = ['is_month_end', 'is_year_end', 'is_quarter_end']
|
||||
for end in ends:
|
||||
assert getattr(ts, end)
|
||||
|
||||
# GH 12806
|
||||
@pytest.mark.parametrize('data',
|
||||
[Timestamp('2017-08-28 23:00:00'),
|
||||
Timestamp('2017-08-28 23:00:00', tz='EST')])
|
||||
@pytest.mark.parametrize('time_locale', [
|
||||
None] if tm.get_locales() is None else [None] + tm.get_locales())
|
||||
def test_names(self, data, time_locale):
|
||||
# GH 17354
|
||||
# Test .weekday_name, .day_name(), .month_name
|
||||
with tm.assert_produces_warning(FutureWarning,
|
||||
check_stacklevel=False):
|
||||
assert data.weekday_name == 'Monday'
|
||||
if time_locale is None:
|
||||
expected_day = 'Monday'
|
||||
expected_month = 'August'
|
||||
else:
|
||||
with tm.set_locale(time_locale, locale.LC_TIME):
|
||||
expected_day = calendar.day_name[0].capitalize()
|
||||
expected_month = calendar.month_name[8].capitalize()
|
||||
|
||||
result_day = data.day_name(time_locale)
|
||||
result_month = data.month_name(time_locale)
|
||||
|
||||
# Work around https://github.com/pandas-dev/pandas/issues/22342
|
||||
# different normalizations
|
||||
|
||||
if not PY2:
|
||||
expected_day = unicodedata.normalize("NFD", expected_day)
|
||||
expected_month = unicodedata.normalize("NFD", expected_month)
|
||||
|
||||
result_day = unicodedata.normalize("NFD", result_day,)
|
||||
result_month = unicodedata.normalize("NFD", result_month)
|
||||
|
||||
assert result_day == expected_day
|
||||
assert result_month == expected_month
|
||||
|
||||
# Test NaT
|
||||
nan_ts = Timestamp(NaT)
|
||||
assert np.isnan(nan_ts.day_name(time_locale))
|
||||
assert np.isnan(nan_ts.month_name(time_locale))
|
||||
|
||||
def test_is_leap_year(self, tz_naive_fixture):
|
||||
tz = tz_naive_fixture
|
||||
# GH 13727
|
||||
dt = Timestamp('2000-01-01 00:00:00', tz=tz)
|
||||
assert dt.is_leap_year
|
||||
assert isinstance(dt.is_leap_year, bool)
|
||||
|
||||
dt = Timestamp('1999-01-01 00:00:00', tz=tz)
|
||||
assert not dt.is_leap_year
|
||||
|
||||
dt = Timestamp('2004-01-01 00:00:00', tz=tz)
|
||||
assert dt.is_leap_year
|
||||
|
||||
dt = Timestamp('2100-01-01 00:00:00', tz=tz)
|
||||
assert not dt.is_leap_year
|
||||
|
||||
def test_woy_boundary(self):
|
||||
# make sure weeks at year boundaries are correct
|
||||
d = datetime(2013, 12, 31)
|
||||
result = Timestamp(d).week
|
||||
expected = 1 # ISO standard
|
||||
assert result == expected
|
||||
|
||||
d = datetime(2008, 12, 28)
|
||||
result = Timestamp(d).week
|
||||
expected = 52 # ISO standard
|
||||
assert result == expected
|
||||
|
||||
d = datetime(2009, 12, 31)
|
||||
result = Timestamp(d).week
|
||||
expected = 53 # ISO standard
|
||||
assert result == expected
|
||||
|
||||
d = datetime(2010, 1, 1)
|
||||
result = Timestamp(d).week
|
||||
expected = 53 # ISO standard
|
||||
assert result == expected
|
||||
|
||||
d = datetime(2010, 1, 3)
|
||||
result = Timestamp(d).week
|
||||
expected = 53 # ISO standard
|
||||
assert result == expected
|
||||
|
||||
result = np.array([Timestamp(datetime(*args)).week
|
||||
for args in [(2000, 1, 1), (2000, 1, 2), (
|
||||
2005, 1, 1), (2005, 1, 2)]])
|
||||
assert (result == [52, 52, 53, 53]).all()
|
||||
|
||||
def test_resolution(self):
|
||||
# GH#21336, GH#21365
|
||||
dt = Timestamp('2100-01-01 00:00:00')
|
||||
assert dt.resolution == Timedelta(nanoseconds=1)
|
||||
|
||||
|
||||
class TestTimestampConstructors(object):
|
||||
|
||||
def test_constructor(self):
|
||||
base_str = '2014-07-01 09:00'
|
||||
base_dt = datetime(2014, 7, 1, 9)
|
||||
base_expected = 1404205200000000000
|
||||
|
||||
# confirm base representation is correct
|
||||
import calendar
|
||||
assert (calendar.timegm(base_dt.timetuple()) * 1000000000 ==
|
||||
base_expected)
|
||||
|
||||
tests = [(base_str, base_dt, base_expected),
|
||||
('2014-07-01 10:00', datetime(2014, 7, 1, 10),
|
||||
base_expected + 3600 * 1000000000),
|
||||
('2014-07-01 09:00:00.000008000',
|
||||
datetime(2014, 7, 1, 9, 0, 0, 8),
|
||||
base_expected + 8000),
|
||||
('2014-07-01 09:00:00.000000005',
|
||||
Timestamp('2014-07-01 09:00:00.000000005'),
|
||||
base_expected + 5)]
|
||||
|
||||
timezones = [(None, 0), ('UTC', 0), (pytz.utc, 0), ('Asia/Tokyo', 9),
|
||||
('US/Eastern', -4), ('dateutil/US/Pacific', -7),
|
||||
(pytz.FixedOffset(-180), -3),
|
||||
(dateutil.tz.tzoffset(None, 18000), 5)]
|
||||
|
||||
for date_str, date, expected in tests:
|
||||
for result in [Timestamp(date_str), Timestamp(date)]:
|
||||
# only with timestring
|
||||
assert result.value == expected
|
||||
assert conversion.pydt_to_i8(result) == expected
|
||||
|
||||
# re-creation shouldn't affect to internal value
|
||||
result = Timestamp(result)
|
||||
assert result.value == expected
|
||||
assert conversion.pydt_to_i8(result) == expected
|
||||
|
||||
# with timezone
|
||||
for tz, offset in timezones:
|
||||
for result in [Timestamp(date_str, tz=tz), Timestamp(date,
|
||||
tz=tz)]:
|
||||
expected_tz = expected - offset * 3600 * 1000000000
|
||||
assert result.value == expected_tz
|
||||
assert conversion.pydt_to_i8(result) == expected_tz
|
||||
|
||||
# should preserve tz
|
||||
result = Timestamp(result)
|
||||
assert result.value == expected_tz
|
||||
assert conversion.pydt_to_i8(result) == expected_tz
|
||||
|
||||
# should convert to UTC
|
||||
if tz is not None:
|
||||
result = Timestamp(result).tz_convert('UTC')
|
||||
else:
|
||||
result = Timestamp(result, tz='UTC')
|
||||
expected_utc = expected - offset * 3600 * 1000000000
|
||||
assert result.value == expected_utc
|
||||
assert conversion.pydt_to_i8(result) == expected_utc
|
||||
|
||||
def test_constructor_with_stringoffset(self):
|
||||
# GH 7833
|
||||
base_str = '2014-07-01 11:00:00+02:00'
|
||||
base_dt = datetime(2014, 7, 1, 9)
|
||||
base_expected = 1404205200000000000
|
||||
|
||||
# confirm base representation is correct
|
||||
import calendar
|
||||
assert (calendar.timegm(base_dt.timetuple()) * 1000000000 ==
|
||||
base_expected)
|
||||
|
||||
tests = [(base_str, base_expected),
|
||||
('2014-07-01 12:00:00+02:00',
|
||||
base_expected + 3600 * 1000000000),
|
||||
('2014-07-01 11:00:00.000008000+02:00', base_expected + 8000),
|
||||
('2014-07-01 11:00:00.000000005+02:00', base_expected + 5)]
|
||||
|
||||
timezones = [(None, 0), ('UTC', 0), (pytz.utc, 0), ('Asia/Tokyo', 9),
|
||||
('US/Eastern', -4), ('dateutil/US/Pacific', -7),
|
||||
(pytz.FixedOffset(-180), -3),
|
||||
(dateutil.tz.tzoffset(None, 18000), 5)]
|
||||
|
||||
for date_str, expected in tests:
|
||||
for result in [Timestamp(date_str)]:
|
||||
# only with timestring
|
||||
assert result.value == expected
|
||||
assert conversion.pydt_to_i8(result) == expected
|
||||
|
||||
# re-creation shouldn't affect to internal value
|
||||
result = Timestamp(result)
|
||||
assert result.value == expected
|
||||
assert conversion.pydt_to_i8(result) == expected
|
||||
|
||||
# with timezone
|
||||
for tz, offset in timezones:
|
||||
result = Timestamp(date_str, tz=tz)
|
||||
expected_tz = expected
|
||||
assert result.value == expected_tz
|
||||
assert conversion.pydt_to_i8(result) == expected_tz
|
||||
|
||||
# should preserve tz
|
||||
result = Timestamp(result)
|
||||
assert result.value == expected_tz
|
||||
assert conversion.pydt_to_i8(result) == expected_tz
|
||||
|
||||
# should convert to UTC
|
||||
result = Timestamp(result).tz_convert('UTC')
|
||||
expected_utc = expected
|
||||
assert result.value == expected_utc
|
||||
assert conversion.pydt_to_i8(result) == expected_utc
|
||||
|
||||
# This should be 2013-11-01 05:00 in UTC
|
||||
# converted to Chicago tz
|
||||
result = Timestamp('2013-11-01 00:00:00-0500', tz='America/Chicago')
|
||||
assert result.value == Timestamp('2013-11-01 05:00').value
|
||||
expected = "Timestamp('2013-11-01 00:00:00-0500', tz='America/Chicago')" # noqa
|
||||
assert repr(result) == expected
|
||||
assert result == eval(repr(result))
|
||||
|
||||
# This should be 2013-11-01 05:00 in UTC
|
||||
# converted to Tokyo tz (+09:00)
|
||||
result = Timestamp('2013-11-01 00:00:00-0500', tz='Asia/Tokyo')
|
||||
assert result.value == Timestamp('2013-11-01 05:00').value
|
||||
expected = "Timestamp('2013-11-01 14:00:00+0900', tz='Asia/Tokyo')"
|
||||
assert repr(result) == expected
|
||||
assert result == eval(repr(result))
|
||||
|
||||
# GH11708
|
||||
# This should be 2015-11-18 10:00 in UTC
|
||||
# converted to Asia/Katmandu
|
||||
result = Timestamp("2015-11-18 15:45:00+05:45", tz="Asia/Katmandu")
|
||||
assert result.value == Timestamp("2015-11-18 10:00").value
|
||||
expected = "Timestamp('2015-11-18 15:45:00+0545', tz='Asia/Katmandu')"
|
||||
assert repr(result) == expected
|
||||
assert result == eval(repr(result))
|
||||
|
||||
# This should be 2015-11-18 10:00 in UTC
|
||||
# converted to Asia/Kolkata
|
||||
result = Timestamp("2015-11-18 15:30:00+05:30", tz="Asia/Kolkata")
|
||||
assert result.value == Timestamp("2015-11-18 10:00").value
|
||||
expected = "Timestamp('2015-11-18 15:30:00+0530', tz='Asia/Kolkata')"
|
||||
assert repr(result) == expected
|
||||
assert result == eval(repr(result))
|
||||
|
||||
def test_constructor_invalid(self):
|
||||
with pytest.raises(TypeError, match='Cannot convert input'):
|
||||
Timestamp(slice(2))
|
||||
with pytest.raises(ValueError, match='Cannot convert Period'):
|
||||
Timestamp(Period('1000-01-01'))
|
||||
|
||||
def test_constructor_invalid_tz(self):
|
||||
# GH#17690
|
||||
with pytest.raises(TypeError, match='must be a datetime.tzinfo'):
|
||||
Timestamp('2017-10-22', tzinfo='US/Eastern')
|
||||
|
||||
with pytest.raises(ValueError, match='at most one of'):
|
||||
Timestamp('2017-10-22', tzinfo=utc, tz='UTC')
|
||||
|
||||
with pytest.raises(ValueError, match="Invalid frequency:"):
|
||||
# GH#5168
|
||||
# case where user tries to pass tz as an arg, not kwarg, gets
|
||||
# interpreted as a `freq`
|
||||
Timestamp('2012-01-01', 'US/Pacific')
|
||||
|
||||
def test_constructor_tz_or_tzinfo(self):
|
||||
# GH#17943, GH#17690, GH#5168
|
||||
stamps = [Timestamp(year=2017, month=10, day=22, tz='UTC'),
|
||||
Timestamp(year=2017, month=10, day=22, tzinfo=utc),
|
||||
Timestamp(year=2017, month=10, day=22, tz=utc),
|
||||
Timestamp(datetime(2017, 10, 22), tzinfo=utc),
|
||||
Timestamp(datetime(2017, 10, 22), tz='UTC'),
|
||||
Timestamp(datetime(2017, 10, 22), tz=utc)]
|
||||
assert all(ts == stamps[0] for ts in stamps)
|
||||
|
||||
def test_constructor_positional(self):
|
||||
# see gh-10758
|
||||
with pytest.raises(TypeError):
|
||||
Timestamp(2000, 1)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(2000, 0, 1)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(2000, 13, 1)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(2000, 1, 0)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(2000, 1, 32)
|
||||
|
||||
# see gh-11630
|
||||
assert (repr(Timestamp(2015, 11, 12)) ==
|
||||
repr(Timestamp('20151112')))
|
||||
assert (repr(Timestamp(2015, 11, 12, 1, 2, 3, 999999)) ==
|
||||
repr(Timestamp('2015-11-12 01:02:03.999999')))
|
||||
|
||||
def test_constructor_keyword(self):
|
||||
# GH 10758
|
||||
with pytest.raises(TypeError):
|
||||
Timestamp(year=2000, month=1)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(year=2000, month=0, day=1)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(year=2000, month=13, day=1)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(year=2000, month=1, day=0)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(year=2000, month=1, day=32)
|
||||
|
||||
assert (repr(Timestamp(year=2015, month=11, day=12)) ==
|
||||
repr(Timestamp('20151112')))
|
||||
|
||||
assert (repr(Timestamp(year=2015, month=11, day=12, hour=1, minute=2,
|
||||
second=3, microsecond=999999)) ==
|
||||
repr(Timestamp('2015-11-12 01:02:03.999999')))
|
||||
|
||||
def test_constructor_fromordinal(self):
|
||||
base = datetime(2000, 1, 1)
|
||||
|
||||
ts = Timestamp.fromordinal(base.toordinal(), freq='D')
|
||||
assert base == ts
|
||||
assert ts.freq == 'D'
|
||||
assert base.toordinal() == ts.toordinal()
|
||||
|
||||
ts = Timestamp.fromordinal(base.toordinal(), tz='US/Eastern')
|
||||
assert Timestamp('2000-01-01', tz='US/Eastern') == ts
|
||||
assert base.toordinal() == ts.toordinal()
|
||||
|
||||
# GH#3042
|
||||
dt = datetime(2011, 4, 16, 0, 0)
|
||||
ts = Timestamp.fromordinal(dt.toordinal())
|
||||
assert ts.to_pydatetime() == dt
|
||||
|
||||
# with a tzinfo
|
||||
stamp = Timestamp('2011-4-16', tz='US/Eastern')
|
||||
dt_tz = stamp.to_pydatetime()
|
||||
ts = Timestamp.fromordinal(dt_tz.toordinal(), tz='US/Eastern')
|
||||
assert ts.to_pydatetime() == dt_tz
|
||||
|
||||
@pytest.mark.parametrize('result', [
|
||||
Timestamp(datetime(2000, 1, 2, 3, 4, 5, 6), nanosecond=1),
|
||||
Timestamp(year=2000, month=1, day=2, hour=3, minute=4, second=5,
|
||||
microsecond=6, nanosecond=1),
|
||||
Timestamp(year=2000, month=1, day=2, hour=3, minute=4, second=5,
|
||||
microsecond=6, nanosecond=1, tz='UTC'),
|
||||
Timestamp(2000, 1, 2, 3, 4, 5, 6, 1, None),
|
||||
Timestamp(2000, 1, 2, 3, 4, 5, 6, 1, pytz.UTC)])
|
||||
def test_constructor_nanosecond(self, result):
|
||||
# GH 18898
|
||||
expected = Timestamp(datetime(2000, 1, 2, 3, 4, 5, 6), tz=result.tz)
|
||||
expected = expected + Timedelta(nanoseconds=1)
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('z', ['Z0', 'Z00'])
|
||||
def test_constructor_invalid_Z0_isostring(self, z):
|
||||
# GH 8910
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp('2014-11-02 01:00{}'.format(z))
|
||||
|
||||
@pytest.mark.parametrize('arg', ['year', 'month', 'day', 'hour', 'minute',
|
||||
'second', 'microsecond', 'nanosecond'])
|
||||
def test_invalid_date_kwarg_with_string_input(self, arg):
|
||||
kwarg = {arg: 1}
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp('2010-10-10 12:59:59.999999999', **kwarg)
|
||||
|
||||
def test_out_of_bounds_value(self):
|
||||
one_us = np.timedelta64(1).astype('timedelta64[us]')
|
||||
|
||||
# By definition we can't go out of bounds in [ns], so we
|
||||
# convert the datetime64s to [us] so we can go out of bounds
|
||||
min_ts_us = np.datetime64(Timestamp.min).astype('M8[us]')
|
||||
max_ts_us = np.datetime64(Timestamp.max).astype('M8[us]')
|
||||
|
||||
# No error for the min/max datetimes
|
||||
Timestamp(min_ts_us)
|
||||
Timestamp(max_ts_us)
|
||||
|
||||
# One us less than the minimum is an error
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(min_ts_us - one_us)
|
||||
|
||||
# One us more than the maximum is an error
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(max_ts_us + one_us)
|
||||
|
||||
def test_out_of_bounds_string(self):
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp('1676-01-01')
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp('2263-01-01')
|
||||
|
||||
def test_barely_out_of_bounds(self):
|
||||
# GH#19529
|
||||
# GH#19382 close enough to bounds that dropping nanos would result
|
||||
# in an in-bounds datetime
|
||||
with pytest.raises(OutOfBoundsDatetime):
|
||||
Timestamp('2262-04-11 23:47:16.854775808')
|
||||
|
||||
def test_bounds_with_different_units(self):
|
||||
out_of_bounds_dates = ('1677-09-21', '2262-04-12')
|
||||
|
||||
time_units = ('D', 'h', 'm', 's', 'ms', 'us')
|
||||
|
||||
for date_string in out_of_bounds_dates:
|
||||
for unit in time_units:
|
||||
dt64 = np.datetime64(date_string, dtype='M8[%s]' % unit)
|
||||
with pytest.raises(ValueError):
|
||||
Timestamp(dt64)
|
||||
|
||||
in_bounds_dates = ('1677-09-23', '2262-04-11')
|
||||
|
||||
for date_string in in_bounds_dates:
|
||||
for unit in time_units:
|
||||
dt64 = np.datetime64(date_string, dtype='M8[%s]' % unit)
|
||||
Timestamp(dt64)
|
||||
|
||||
def test_min_valid(self):
|
||||
# Ensure that Timestamp.min is a valid Timestamp
|
||||
Timestamp(Timestamp.min)
|
||||
|
||||
def test_max_valid(self):
|
||||
# Ensure that Timestamp.max is a valid Timestamp
|
||||
Timestamp(Timestamp.max)
|
||||
|
||||
def test_now(self):
|
||||
# GH#9000
|
||||
ts_from_string = Timestamp('now')
|
||||
ts_from_method = Timestamp.now()
|
||||
ts_datetime = datetime.now()
|
||||
|
||||
ts_from_string_tz = Timestamp('now', tz='US/Eastern')
|
||||
ts_from_method_tz = Timestamp.now(tz='US/Eastern')
|
||||
|
||||
# Check that the delta between the times is less than 1s (arbitrarily
|
||||
# small)
|
||||
delta = Timedelta(seconds=1)
|
||||
assert abs(ts_from_method - ts_from_string) < delta
|
||||
assert abs(ts_datetime - ts_from_method) < delta
|
||||
assert abs(ts_from_method_tz - ts_from_string_tz) < delta
|
||||
assert (abs(ts_from_string_tz.tz_localize(None) -
|
||||
ts_from_method_tz.tz_localize(None)) < delta)
|
||||
|
||||
def test_today(self):
|
||||
ts_from_string = Timestamp('today')
|
||||
ts_from_method = Timestamp.today()
|
||||
ts_datetime = datetime.today()
|
||||
|
||||
ts_from_string_tz = Timestamp('today', tz='US/Eastern')
|
||||
ts_from_method_tz = Timestamp.today(tz='US/Eastern')
|
||||
|
||||
# Check that the delta between the times is less than 1s (arbitrarily
|
||||
# small)
|
||||
delta = Timedelta(seconds=1)
|
||||
assert abs(ts_from_method - ts_from_string) < delta
|
||||
assert abs(ts_datetime - ts_from_method) < delta
|
||||
assert abs(ts_from_method_tz - ts_from_string_tz) < delta
|
||||
assert (abs(ts_from_string_tz.tz_localize(None) -
|
||||
ts_from_method_tz.tz_localize(None)) < delta)
|
||||
|
||||
@pytest.mark.parametrize('tz', [None, pytz.timezone('US/Pacific')])
|
||||
def test_disallow_setting_tz(self, tz):
|
||||
# GH 3746
|
||||
ts = Timestamp('2010')
|
||||
with pytest.raises(AttributeError):
|
||||
ts.tz = tz
|
||||
|
||||
@pytest.mark.parametrize('offset', ['+0300', '+0200'])
|
||||
def test_construct_timestamp_near_dst(self, offset):
|
||||
# GH 20854
|
||||
expected = Timestamp('2016-10-30 03:00:00{}'.format(offset),
|
||||
tz='Europe/Helsinki')
|
||||
result = Timestamp(expected).tz_convert('Europe/Helsinki')
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('arg', [
|
||||
'2013/01/01 00:00:00+09:00', '2013-01-01 00:00:00+09:00'])
|
||||
def test_construct_with_different_string_format(self, arg):
|
||||
# GH 12064
|
||||
result = Timestamp(arg)
|
||||
expected = Timestamp(datetime(2013, 1, 1), tz=pytz.FixedOffset(540))
|
||||
assert result == expected
|
||||
|
||||
def test_construct_timestamp_preserve_original_frequency(self):
|
||||
# GH 22311
|
||||
result = Timestamp(Timestamp('2010-08-08', freq='D')).freq
|
||||
expected = offsets.Day()
|
||||
assert result == expected
|
||||
|
||||
def test_constructor_invalid_frequency(self):
|
||||
# GH 22311
|
||||
with pytest.raises(ValueError, match="Invalid frequency:"):
|
||||
Timestamp('2012-01-01', freq=[])
|
||||
|
||||
@pytest.mark.parametrize('box', [datetime, Timestamp])
|
||||
def test_depreciate_tz_and_tzinfo_in_datetime_input(self, box):
|
||||
# GH 23579
|
||||
kwargs = {'year': 2018, 'month': 1, 'day': 1, 'tzinfo': utc}
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
Timestamp(box(**kwargs), tz='US/Pacific')
|
||||
|
||||
def test_dont_convert_dateutil_utc_to_pytz_utc(self):
|
||||
result = Timestamp(datetime(2018, 1, 1), tz=tzutc())
|
||||
expected = Timestamp(datetime(2018, 1, 1)).tz_localize(tzutc())
|
||||
assert result == expected
|
||||
|
||||
|
||||
class TestTimestamp(object):
|
||||
|
||||
def test_tz(self):
|
||||
tstr = '2014-02-01 09:00'
|
||||
ts = Timestamp(tstr)
|
||||
local = ts.tz_localize('Asia/Tokyo')
|
||||
assert local.hour == 9
|
||||
assert local == Timestamp(tstr, tz='Asia/Tokyo')
|
||||
conv = local.tz_convert('US/Eastern')
|
||||
assert conv == Timestamp('2014-01-31 19:00', tz='US/Eastern')
|
||||
assert conv.hour == 19
|
||||
|
||||
# preserves nanosecond
|
||||
ts = Timestamp(tstr) + offsets.Nano(5)
|
||||
local = ts.tz_localize('Asia/Tokyo')
|
||||
assert local.hour == 9
|
||||
assert local.nanosecond == 5
|
||||
conv = local.tz_convert('US/Eastern')
|
||||
assert conv.nanosecond == 5
|
||||
assert conv.hour == 19
|
||||
|
||||
def test_utc_z_designator(self):
|
||||
assert get_timezone(Timestamp('2014-11-02 01:00Z').tzinfo) is utc
|
||||
|
||||
def test_asm8(self):
|
||||
np.random.seed(7960929)
|
||||
ns = [Timestamp.min.value, Timestamp.max.value, 1000]
|
||||
|
||||
for n in ns:
|
||||
assert (Timestamp(n).asm8.view('i8') ==
|
||||
np.datetime64(n, 'ns').view('i8') == n)
|
||||
|
||||
assert (Timestamp('nat').asm8.view('i8') ==
|
||||
np.datetime64('nat', 'ns').view('i8'))
|
||||
|
||||
def test_class_ops_pytz(self):
|
||||
def compare(x, y):
|
||||
assert (int(Timestamp(x).value / 1e9) ==
|
||||
int(Timestamp(y).value / 1e9))
|
||||
|
||||
compare(Timestamp.now(), datetime.now())
|
||||
compare(Timestamp.now('UTC'), datetime.now(timezone('UTC')))
|
||||
compare(Timestamp.utcnow(), datetime.utcnow())
|
||||
compare(Timestamp.today(), datetime.today())
|
||||
current_time = calendar.timegm(datetime.now().utctimetuple())
|
||||
compare(Timestamp.utcfromtimestamp(current_time),
|
||||
datetime.utcfromtimestamp(current_time))
|
||||
compare(Timestamp.fromtimestamp(current_time),
|
||||
datetime.fromtimestamp(current_time))
|
||||
|
||||
date_component = datetime.utcnow()
|
||||
time_component = (date_component + timedelta(minutes=10)).time()
|
||||
compare(Timestamp.combine(date_component, time_component),
|
||||
datetime.combine(date_component, time_component))
|
||||
|
||||
def test_class_ops_dateutil(self):
|
||||
def compare(x, y):
|
||||
assert (int(np.round(Timestamp(x).value / 1e9)) ==
|
||||
int(np.round(Timestamp(y).value / 1e9)))
|
||||
|
||||
compare(Timestamp.now(), datetime.now())
|
||||
compare(Timestamp.now('UTC'), datetime.now(tzutc()))
|
||||
compare(Timestamp.utcnow(), datetime.utcnow())
|
||||
compare(Timestamp.today(), datetime.today())
|
||||
current_time = calendar.timegm(datetime.now().utctimetuple())
|
||||
compare(Timestamp.utcfromtimestamp(current_time),
|
||||
datetime.utcfromtimestamp(current_time))
|
||||
compare(Timestamp.fromtimestamp(current_time),
|
||||
datetime.fromtimestamp(current_time))
|
||||
|
||||
date_component = datetime.utcnow()
|
||||
time_component = (date_component + timedelta(minutes=10)).time()
|
||||
compare(Timestamp.combine(date_component, time_component),
|
||||
datetime.combine(date_component, time_component))
|
||||
|
||||
def test_basics_nanos(self):
|
||||
val = np.int64(946684800000000000).view('M8[ns]')
|
||||
stamp = Timestamp(val.view('i8') + 500)
|
||||
assert stamp.year == 2000
|
||||
assert stamp.month == 1
|
||||
assert stamp.microsecond == 0
|
||||
assert stamp.nanosecond == 500
|
||||
|
||||
# GH 14415
|
||||
val = np.iinfo(np.int64).min + 80000000000000
|
||||
stamp = Timestamp(val)
|
||||
assert stamp.year == 1677
|
||||
assert stamp.month == 9
|
||||
assert stamp.day == 21
|
||||
assert stamp.microsecond == 145224
|
||||
assert stamp.nanosecond == 192
|
||||
|
||||
@pytest.mark.parametrize('value, check_kwargs', [
|
||||
[946688461000000000, {}],
|
||||
[946688461000000000 / long(1000), dict(unit='us')],
|
||||
[946688461000000000 / long(1000000), dict(unit='ms')],
|
||||
[946688461000000000 / long(1000000000), dict(unit='s')],
|
||||
[10957, dict(unit='D', h=0)],
|
||||
pytest.param((946688461000000000 + 500000) / long(1000000000),
|
||||
dict(unit='s', us=499, ns=964),
|
||||
marks=pytest.mark.skipif(not PY3,
|
||||
reason='using truediv, so these'
|
||||
' are like floats')),
|
||||
pytest.param((946688461000000000 + 500000000) / long(1000000000),
|
||||
dict(unit='s', us=500000),
|
||||
marks=pytest.mark.skipif(not PY3,
|
||||
reason='using truediv, so these'
|
||||
' are like floats')),
|
||||
pytest.param((946688461000000000 + 500000) / long(1000000),
|
||||
dict(unit='ms', us=500),
|
||||
marks=pytest.mark.skipif(not PY3,
|
||||
reason='using truediv, so these'
|
||||
' are like floats')),
|
||||
pytest.param((946688461000000000 + 500000) / long(1000000000),
|
||||
dict(unit='s'),
|
||||
marks=pytest.mark.skipif(PY3,
|
||||
reason='get chopped in py2')),
|
||||
pytest.param((946688461000000000 + 500000000) / long(1000000000),
|
||||
dict(unit='s'),
|
||||
marks=pytest.mark.skipif(PY3,
|
||||
reason='get chopped in py2')),
|
||||
pytest.param((946688461000000000 + 500000) / long(1000000),
|
||||
dict(unit='ms'),
|
||||
marks=pytest.mark.skipif(PY3,
|
||||
reason='get chopped in py2')),
|
||||
[(946688461000000000 + 500000) / long(1000), dict(unit='us', us=500)],
|
||||
[(946688461000000000 + 500000000) / long(1000000),
|
||||
dict(unit='ms', us=500000)],
|
||||
[946688461000000000 / 1000.0 + 5, dict(unit='us', us=5)],
|
||||
[946688461000000000 / 1000.0 + 5000, dict(unit='us', us=5000)],
|
||||
[946688461000000000 / 1000000.0 + 0.5, dict(unit='ms', us=500)],
|
||||
[946688461000000000 / 1000000.0 + 0.005, dict(unit='ms', us=5, ns=5)],
|
||||
[946688461000000000 / 1000000000.0 + 0.5, dict(unit='s', us=500000)],
|
||||
[10957 + 0.5, dict(unit='D', h=12)]])
|
||||
def test_unit(self, value, check_kwargs):
|
||||
def check(value, unit=None, h=1, s=1, us=0, ns=0):
|
||||
stamp = Timestamp(value, unit=unit)
|
||||
assert stamp.year == 2000
|
||||
assert stamp.month == 1
|
||||
assert stamp.day == 1
|
||||
assert stamp.hour == h
|
||||
if unit != 'D':
|
||||
assert stamp.minute == 1
|
||||
assert stamp.second == s
|
||||
assert stamp.microsecond == us
|
||||
else:
|
||||
assert stamp.minute == 0
|
||||
assert stamp.second == 0
|
||||
assert stamp.microsecond == 0
|
||||
assert stamp.nanosecond == ns
|
||||
|
||||
check(value, **check_kwargs)
|
||||
|
||||
def test_roundtrip(self):
|
||||
|
||||
# test value to string and back conversions
|
||||
# further test accessors
|
||||
base = Timestamp('20140101 00:00:00')
|
||||
|
||||
result = Timestamp(base.value + Timedelta('5ms').value)
|
||||
assert result == Timestamp(str(base) + ".005000")
|
||||
assert result.microsecond == 5000
|
||||
|
||||
result = Timestamp(base.value + Timedelta('5us').value)
|
||||
assert result == Timestamp(str(base) + ".000005")
|
||||
assert result.microsecond == 5
|
||||
|
||||
result = Timestamp(base.value + Timedelta('5ns').value)
|
||||
assert result == Timestamp(str(base) + ".000000005")
|
||||
assert result.nanosecond == 5
|
||||
assert result.microsecond == 0
|
||||
|
||||
result = Timestamp(base.value + Timedelta('6ms 5us').value)
|
||||
assert result == Timestamp(str(base) + ".006005")
|
||||
assert result.microsecond == 5 + 6 * 1000
|
||||
|
||||
result = Timestamp(base.value + Timedelta('200ms 5us').value)
|
||||
assert result == Timestamp(str(base) + ".200005")
|
||||
assert result.microsecond == 5 + 200 * 1000
|
||||
|
||||
def test_hash_equivalent(self):
|
||||
d = {datetime(2011, 1, 1): 5}
|
||||
stamp = Timestamp(datetime(2011, 1, 1))
|
||||
assert d[stamp] == 5
|
||||
|
||||
|
||||
class TestTimestampNsOperations(object):
|
||||
|
||||
def setup_method(self, method):
|
||||
self.timestamp = Timestamp(datetime.utcnow())
|
||||
|
||||
def assert_ns_timedelta(self, modified_timestamp, expected_value):
|
||||
value = self.timestamp.value
|
||||
modified_value = modified_timestamp.value
|
||||
|
||||
assert modified_value - value == expected_value
|
||||
|
||||
def test_timedelta_ns_arithmetic(self):
|
||||
self.assert_ns_timedelta(self.timestamp + np.timedelta64(-123, 'ns'),
|
||||
-123)
|
||||
|
||||
def test_timedelta_ns_based_arithmetic(self):
|
||||
self.assert_ns_timedelta(self.timestamp + np.timedelta64(
|
||||
1234567898, 'ns'), 1234567898)
|
||||
|
||||
def test_timedelta_us_arithmetic(self):
|
||||
self.assert_ns_timedelta(self.timestamp + np.timedelta64(-123, 'us'),
|
||||
-123000)
|
||||
|
||||
def test_timedelta_ms_arithmetic(self):
|
||||
time = self.timestamp + np.timedelta64(-123, 'ms')
|
||||
self.assert_ns_timedelta(time, -123000000)
|
||||
|
||||
def test_nanosecond_string_parsing(self):
|
||||
ts = Timestamp('2013-05-01 07:15:45.123456789')
|
||||
# GH 7878
|
||||
expected_repr = '2013-05-01 07:15:45.123456789'
|
||||
expected_value = 1367392545123456789
|
||||
assert ts.value == expected_value
|
||||
assert expected_repr in repr(ts)
|
||||
|
||||
ts = Timestamp('2013-05-01 07:15:45.123456789+09:00', tz='Asia/Tokyo')
|
||||
assert ts.value == expected_value - 9 * 3600 * 1000000000
|
||||
assert expected_repr in repr(ts)
|
||||
|
||||
ts = Timestamp('2013-05-01 07:15:45.123456789', tz='UTC')
|
||||
assert ts.value == expected_value
|
||||
assert expected_repr in repr(ts)
|
||||
|
||||
ts = Timestamp('2013-05-01 07:15:45.123456789', tz='US/Eastern')
|
||||
assert ts.value == expected_value + 4 * 3600 * 1000000000
|
||||
assert expected_repr in repr(ts)
|
||||
|
||||
# GH 10041
|
||||
ts = Timestamp('20130501T071545.123456789')
|
||||
assert ts.value == expected_value
|
||||
assert expected_repr in repr(ts)
|
||||
|
||||
def test_nanosecond_timestamp(self):
|
||||
# GH 7610
|
||||
expected = 1293840000000000005
|
||||
t = Timestamp('2011-01-01') + offsets.Nano(5)
|
||||
assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
|
||||
assert t.value == expected
|
||||
assert t.nanosecond == 5
|
||||
|
||||
t = Timestamp(t)
|
||||
assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
|
||||
assert t.value == expected
|
||||
assert t.nanosecond == 5
|
||||
|
||||
t = Timestamp(np_datetime64_compat('2011-01-01 00:00:00.000000005Z'))
|
||||
assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
|
||||
assert t.value == expected
|
||||
assert t.nanosecond == 5
|
||||
|
||||
expected = 1293840000000000010
|
||||
t = t + offsets.Nano(5)
|
||||
assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
|
||||
assert t.value == expected
|
||||
assert t.nanosecond == 10
|
||||
|
||||
t = Timestamp(t)
|
||||
assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
|
||||
assert t.value == expected
|
||||
assert t.nanosecond == 10
|
||||
|
||||
t = Timestamp(np_datetime64_compat('2011-01-01 00:00:00.000000010Z'))
|
||||
assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
|
||||
assert t.value == expected
|
||||
assert t.nanosecond == 10
|
||||
|
||||
|
||||
class TestTimestampToJulianDate(object):
|
||||
|
||||
def test_compare_1700(self):
|
||||
r = Timestamp('1700-06-23').to_julian_date()
|
||||
assert r == 2342145.5
|
||||
|
||||
def test_compare_2000(self):
|
||||
r = Timestamp('2000-04-12').to_julian_date()
|
||||
assert r == 2451646.5
|
||||
|
||||
def test_compare_2100(self):
|
||||
r = Timestamp('2100-08-12').to_julian_date()
|
||||
assert r == 2488292.5
|
||||
|
||||
def test_compare_hour01(self):
|
||||
r = Timestamp('2000-08-12T01:00:00').to_julian_date()
|
||||
assert r == 2451768.5416666666666666
|
||||
|
||||
def test_compare_hour13(self):
|
||||
r = Timestamp('2000-08-12T13:00:00').to_julian_date()
|
||||
assert r == 2451769.0416666666666666
|
||||
|
||||
|
||||
class TestTimestampConversion(object):
|
||||
def test_conversion(self):
|
||||
# GH#9255
|
||||
ts = Timestamp('2000-01-01')
|
||||
|
||||
result = ts.to_pydatetime()
|
||||
expected = datetime(2000, 1, 1)
|
||||
assert result == expected
|
||||
assert type(result) == type(expected)
|
||||
|
||||
result = ts.to_datetime64()
|
||||
expected = np.datetime64(ts.value, 'ns')
|
||||
assert result == expected
|
||||
assert type(result) == type(expected)
|
||||
assert result.dtype == expected.dtype
|
||||
|
||||
def test_to_pydatetime_nonzero_nano(self):
|
||||
ts = Timestamp('2011-01-01 9:00:00.123456789')
|
||||
|
||||
# Warn the user of data loss (nanoseconds).
|
||||
with tm.assert_produces_warning(UserWarning,
|
||||
check_stacklevel=False):
|
||||
expected = datetime(2011, 1, 1, 9, 0, 0, 123456)
|
||||
result = ts.to_pydatetime()
|
||||
assert result == expected
|
||||
|
||||
def test_timestamp_to_datetime(self):
|
||||
stamp = Timestamp('20090415', tz='US/Eastern', freq='D')
|
||||
dtval = stamp.to_pydatetime()
|
||||
assert stamp == dtval
|
||||
assert stamp.tzinfo == dtval.tzinfo
|
||||
|
||||
def test_timestamp_to_datetime_dateutil(self):
|
||||
stamp = Timestamp('20090415', tz='dateutil/US/Eastern', freq='D')
|
||||
dtval = stamp.to_pydatetime()
|
||||
assert stamp == dtval
|
||||
assert stamp.tzinfo == dtval.tzinfo
|
||||
|
||||
def test_timestamp_to_datetime_explicit_pytz(self):
|
||||
stamp = Timestamp('20090415', tz=pytz.timezone('US/Eastern'), freq='D')
|
||||
dtval = stamp.to_pydatetime()
|
||||
assert stamp == dtval
|
||||
assert stamp.tzinfo == dtval.tzinfo
|
||||
|
||||
@td.skip_if_windows_python_3
|
||||
def test_timestamp_to_datetime_explicit_dateutil(self):
|
||||
stamp = Timestamp('20090415', tz=gettz('US/Eastern'), freq='D')
|
||||
dtval = stamp.to_pydatetime()
|
||||
assert stamp == dtval
|
||||
assert stamp.tzinfo == dtval.tzinfo
|
||||
|
||||
def test_to_datetime_bijective(self):
|
||||
# Ensure that converting to datetime and back only loses precision
|
||||
# by going from nanoseconds to microseconds.
|
||||
exp_warning = None if Timestamp.max.nanosecond == 0 else UserWarning
|
||||
with tm.assert_produces_warning(exp_warning, check_stacklevel=False):
|
||||
assert (Timestamp(Timestamp.max.to_pydatetime()).value / 1000 ==
|
||||
Timestamp.max.value / 1000)
|
||||
|
||||
exp_warning = None if Timestamp.min.nanosecond == 0 else UserWarning
|
||||
with tm.assert_produces_warning(exp_warning, check_stacklevel=False):
|
||||
assert (Timestamp(Timestamp.min.to_pydatetime()).value / 1000 ==
|
||||
Timestamp.min.value / 1000)
|
||||
|
||||
def test_to_period_tz_warning(self):
|
||||
# GH#21333 make sure a warning is issued when timezone
|
||||
# info is lost
|
||||
ts = Timestamp('2009-04-15 16:17:18', tz='US/Eastern')
|
||||
with tm.assert_produces_warning(UserWarning):
|
||||
# warning that timezone info will be lost
|
||||
ts.to_period('D')
|
||||
+389
@@ -0,0 +1,389 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Tests for Timestamp timezone-related methods
|
||||
"""
|
||||
from datetime import date, datetime, timedelta
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
import dateutil
|
||||
from dateutil.tz import gettz, tzoffset
|
||||
import pytest
|
||||
import pytz
|
||||
from pytz.exceptions import AmbiguousTimeError, NonExistentTimeError
|
||||
|
||||
from pandas._libs.tslibs import timezones
|
||||
from pandas.errors import OutOfBoundsDatetime
|
||||
import pandas.util._test_decorators as td
|
||||
|
||||
from pandas import NaT, Timestamp
|
||||
import pandas.util.testing as tm
|
||||
|
||||
|
||||
class TestTimestampTZOperations(object):
|
||||
# --------------------------------------------------------------
|
||||
# Timestamp.tz_localize
|
||||
|
||||
def test_tz_localize_pushes_out_of_bounds(self):
|
||||
# GH#12677
|
||||
# tz_localize that pushes away from the boundary is OK
|
||||
pac = Timestamp.min.tz_localize('US/Pacific')
|
||||
assert pac.value > Timestamp.min.value
|
||||
pac.tz_convert('Asia/Tokyo') # tz_convert doesn't change value
|
||||
with pytest.raises(OutOfBoundsDatetime):
|
||||
Timestamp.min.tz_localize('Asia/Tokyo')
|
||||
|
||||
# tz_localize that pushes away from the boundary is OK
|
||||
tokyo = Timestamp.max.tz_localize('Asia/Tokyo')
|
||||
assert tokyo.value < Timestamp.max.value
|
||||
tokyo.tz_convert('US/Pacific') # tz_convert doesn't change value
|
||||
with pytest.raises(OutOfBoundsDatetime):
|
||||
Timestamp.max.tz_localize('US/Pacific')
|
||||
|
||||
def test_tz_localize_ambiguous_bool(self):
|
||||
# make sure that we are correctly accepting bool values as ambiguous
|
||||
# GH#14402
|
||||
ts = Timestamp('2015-11-01 01:00:03')
|
||||
expected0 = Timestamp('2015-11-01 01:00:03-0500', tz='US/Central')
|
||||
expected1 = Timestamp('2015-11-01 01:00:03-0600', tz='US/Central')
|
||||
|
||||
with pytest.raises(pytz.AmbiguousTimeError):
|
||||
ts.tz_localize('US/Central')
|
||||
|
||||
result = ts.tz_localize('US/Central', ambiguous=True)
|
||||
assert result == expected0
|
||||
|
||||
result = ts.tz_localize('US/Central', ambiguous=False)
|
||||
assert result == expected1
|
||||
|
||||
def test_tz_localize_ambiguous(self):
|
||||
ts = Timestamp('2014-11-02 01:00')
|
||||
ts_dst = ts.tz_localize('US/Eastern', ambiguous=True)
|
||||
ts_no_dst = ts.tz_localize('US/Eastern', ambiguous=False)
|
||||
|
||||
assert (ts_no_dst.value - ts_dst.value) / 1e9 == 3600
|
||||
with pytest.raises(ValueError):
|
||||
ts.tz_localize('US/Eastern', ambiguous='infer')
|
||||
|
||||
# GH#8025
|
||||
msg = ('Cannot localize tz-aware Timestamp, '
|
||||
'use tz_convert for conversions')
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
Timestamp('2011-01-01', tz='US/Eastern').tz_localize('Asia/Tokyo')
|
||||
|
||||
msg = ('Cannot convert tz-naive Timestamp, '
|
||||
'use tz_localize to localize')
|
||||
with pytest.raises(TypeError, match=msg):
|
||||
Timestamp('2011-01-01').tz_convert('Asia/Tokyo')
|
||||
|
||||
@pytest.mark.parametrize('stamp, tz', [
|
||||
('2015-03-08 02:00', 'US/Eastern'),
|
||||
('2015-03-08 02:30', 'US/Pacific'),
|
||||
('2015-03-29 02:00', 'Europe/Paris'),
|
||||
('2015-03-29 02:30', 'Europe/Belgrade')])
|
||||
@pytest.mark.filterwarnings('ignore::FutureWarning')
|
||||
def test_tz_localize_nonexistent(self, stamp, tz):
|
||||
# GH#13057
|
||||
ts = Timestamp(stamp)
|
||||
with pytest.raises(NonExistentTimeError):
|
||||
ts.tz_localize(tz)
|
||||
# GH 22644
|
||||
with pytest.raises(NonExistentTimeError):
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
ts.tz_localize(tz, errors='raise')
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
assert ts.tz_localize(tz, errors='coerce') is NaT
|
||||
|
||||
def test_tz_localize_errors_ambiguous(self):
|
||||
# GH#13057
|
||||
ts = Timestamp('2015-11-1 01:00')
|
||||
with pytest.raises(AmbiguousTimeError):
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
ts.tz_localize('US/Pacific', errors='coerce')
|
||||
|
||||
@pytest.mark.filterwarnings('ignore::FutureWarning')
|
||||
def test_tz_localize_errors_invalid_arg(self):
|
||||
# GH 22644
|
||||
tz = 'Europe/Warsaw'
|
||||
ts = Timestamp('2015-03-29 02:00:00')
|
||||
with pytest.raises(ValueError):
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
ts.tz_localize(tz, errors='foo')
|
||||
|
||||
def test_tz_localize_errors_coerce(self):
|
||||
# GH 22644
|
||||
# make sure errors='coerce' gets mapped correctly to nonexistent
|
||||
tz = 'Europe/Warsaw'
|
||||
ts = Timestamp('2015-03-29 02:00:00')
|
||||
with tm.assert_produces_warning(FutureWarning):
|
||||
result = ts.tz_localize(tz, errors='coerce')
|
||||
expected = ts.tz_localize(tz, nonexistent='NaT')
|
||||
assert result is expected
|
||||
|
||||
@pytest.mark.parametrize('stamp', ['2014-02-01 09:00', '2014-07-08 09:00',
|
||||
'2014-11-01 17:00', '2014-11-05 00:00'])
|
||||
def test_tz_localize_roundtrip(self, stamp, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
ts = Timestamp(stamp)
|
||||
localized = ts.tz_localize(tz)
|
||||
assert localized == Timestamp(stamp, tz=tz)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
localized.tz_localize(tz)
|
||||
|
||||
reset = localized.tz_localize(None)
|
||||
assert reset == ts
|
||||
assert reset.tzinfo is None
|
||||
|
||||
def test_tz_localize_ambiguous_compat(self):
|
||||
# validate that pytz and dateutil are compat for dst
|
||||
# when the transition happens
|
||||
naive = Timestamp('2013-10-27 01:00:00')
|
||||
|
||||
pytz_zone = 'Europe/London'
|
||||
dateutil_zone = 'dateutil/Europe/London'
|
||||
result_pytz = naive.tz_localize(pytz_zone, ambiguous=0)
|
||||
result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=0)
|
||||
assert result_pytz.value == result_dateutil.value
|
||||
assert result_pytz.value == 1382835600000000000
|
||||
|
||||
if LooseVersion(dateutil.__version__) < LooseVersion('2.6.0'):
|
||||
# dateutil 2.6 buggy w.r.t. ambiguous=0
|
||||
# see gh-14621
|
||||
# see https://github.com/dateutil/dateutil/issues/321
|
||||
assert (result_pytz.to_pydatetime().tzname() ==
|
||||
result_dateutil.to_pydatetime().tzname())
|
||||
assert str(result_pytz) == str(result_dateutil)
|
||||
elif LooseVersion(dateutil.__version__) > LooseVersion('2.6.0'):
|
||||
# fixed ambiguous behavior
|
||||
assert result_pytz.to_pydatetime().tzname() == 'GMT'
|
||||
assert result_dateutil.to_pydatetime().tzname() == 'BST'
|
||||
assert str(result_pytz) != str(result_dateutil)
|
||||
|
||||
# 1 hour difference
|
||||
result_pytz = naive.tz_localize(pytz_zone, ambiguous=1)
|
||||
result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=1)
|
||||
assert result_pytz.value == result_dateutil.value
|
||||
assert result_pytz.value == 1382832000000000000
|
||||
|
||||
# dateutil < 2.6 is buggy w.r.t. ambiguous timezones
|
||||
if LooseVersion(dateutil.__version__) > LooseVersion('2.5.3'):
|
||||
# see gh-14621
|
||||
assert str(result_pytz) == str(result_dateutil)
|
||||
assert (result_pytz.to_pydatetime().tzname() ==
|
||||
result_dateutil.to_pydatetime().tzname())
|
||||
|
||||
@pytest.mark.parametrize('tz', [pytz.timezone('US/Eastern'),
|
||||
gettz('US/Eastern'),
|
||||
'US/Eastern', 'dateutil/US/Eastern'])
|
||||
def test_timestamp_tz_localize(self, tz):
|
||||
stamp = Timestamp('3/11/2012 04:00')
|
||||
|
||||
result = stamp.tz_localize(tz)
|
||||
expected = Timestamp('3/11/2012 04:00', tz=tz)
|
||||
assert result.hour == expected.hour
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('start_ts, tz, end_ts, shift', [
|
||||
['2015-03-29 02:20:00', 'Europe/Warsaw', '2015-03-29 03:00:00',
|
||||
'forward'],
|
||||
['2015-03-29 02:20:00', 'Europe/Warsaw',
|
||||
'2015-03-29 01:59:59.999999999', 'backward'],
|
||||
['2015-03-29 02:20:00', 'Europe/Warsaw',
|
||||
'2015-03-29 03:20:00', timedelta(hours=1)],
|
||||
['2015-03-29 02:20:00', 'Europe/Warsaw',
|
||||
'2015-03-29 01:20:00', timedelta(hours=-1)],
|
||||
['2018-03-11 02:33:00', 'US/Pacific', '2018-03-11 03:00:00',
|
||||
'forward'],
|
||||
['2018-03-11 02:33:00', 'US/Pacific', '2018-03-11 01:59:59.999999999',
|
||||
'backward'],
|
||||
['2018-03-11 02:33:00', 'US/Pacific', '2018-03-11 03:33:00',
|
||||
timedelta(hours=1)],
|
||||
['2018-03-11 02:33:00', 'US/Pacific', '2018-03-11 01:33:00',
|
||||
timedelta(hours=-1)]
|
||||
])
|
||||
@pytest.mark.parametrize('tz_type', ['', 'dateutil/'])
|
||||
def test_timestamp_tz_localize_nonexistent_shift(self, start_ts, tz,
|
||||
end_ts, shift,
|
||||
tz_type):
|
||||
# GH 8917, 24466
|
||||
tz = tz_type + tz
|
||||
if isinstance(shift, str):
|
||||
shift = 'shift_' + shift
|
||||
ts = Timestamp(start_ts)
|
||||
result = ts.tz_localize(tz, nonexistent=shift)
|
||||
expected = Timestamp(end_ts).tz_localize(tz)
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('offset', [-1, 1])
|
||||
@pytest.mark.parametrize('tz_type', ['', 'dateutil/'])
|
||||
def test_timestamp_tz_localize_nonexistent_shift_invalid(self, offset,
|
||||
tz_type):
|
||||
# GH 8917, 24466
|
||||
tz = tz_type + 'Europe/Warsaw'
|
||||
ts = Timestamp('2015-03-29 02:20:00')
|
||||
msg = "The provided timedelta will relocalize on a nonexistent time"
|
||||
with pytest.raises(ValueError, match=msg):
|
||||
ts.tz_localize(tz, nonexistent=timedelta(seconds=offset))
|
||||
|
||||
@pytest.mark.parametrize('tz', ['Europe/Warsaw', 'dateutil/Europe/Warsaw'])
|
||||
def test_timestamp_tz_localize_nonexistent_NaT(self, tz):
|
||||
# GH 8917
|
||||
ts = Timestamp('2015-03-29 02:20:00')
|
||||
result = ts.tz_localize(tz, nonexistent='NaT')
|
||||
assert result is NaT
|
||||
|
||||
@pytest.mark.parametrize('tz', ['Europe/Warsaw', 'dateutil/Europe/Warsaw'])
|
||||
def test_timestamp_tz_localize_nonexistent_raise(self, tz):
|
||||
# GH 8917
|
||||
ts = Timestamp('2015-03-29 02:20:00')
|
||||
with pytest.raises(pytz.NonExistentTimeError):
|
||||
ts.tz_localize(tz, nonexistent='raise')
|
||||
with pytest.raises(ValueError):
|
||||
ts.tz_localize(tz, nonexistent='foo')
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Timestamp.tz_convert
|
||||
|
||||
@pytest.mark.parametrize('stamp', ['2014-02-01 09:00', '2014-07-08 09:00',
|
||||
'2014-11-01 17:00', '2014-11-05 00:00'])
|
||||
def test_tz_convert_roundtrip(self, stamp, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
|
||||
ts = Timestamp(stamp, tz='UTC')
|
||||
converted = ts.tz_convert(tz)
|
||||
|
||||
reset = converted.tz_convert(None)
|
||||
assert reset == Timestamp(stamp)
|
||||
assert reset.tzinfo is None
|
||||
assert reset == converted.tz_convert('UTC').tz_localize(None)
|
||||
|
||||
@pytest.mark.parametrize('tzstr', ['US/Eastern', 'dateutil/US/Eastern'])
|
||||
def test_astimezone(self, tzstr):
|
||||
# astimezone is an alias for tz_convert, so keep it with
|
||||
# the tz_convert tests
|
||||
utcdate = Timestamp('3/11/2012 22:00', tz='UTC')
|
||||
expected = utcdate.tz_convert(tzstr)
|
||||
result = utcdate.astimezone(tzstr)
|
||||
assert expected == result
|
||||
assert isinstance(result, Timestamp)
|
||||
|
||||
@td.skip_if_windows
|
||||
def test_tz_convert_utc_with_system_utc(self):
|
||||
from pandas._libs.tslibs.timezones import maybe_get_tz
|
||||
|
||||
# from system utc to real utc
|
||||
ts = Timestamp('2001-01-05 11:56', tz=maybe_get_tz('dateutil/UTC'))
|
||||
# check that the time hasn't changed.
|
||||
assert ts == ts.tz_convert(dateutil.tz.tzutc())
|
||||
|
||||
# from system utc to real utc
|
||||
ts = Timestamp('2001-01-05 11:56', tz=maybe_get_tz('dateutil/UTC'))
|
||||
# check that the time hasn't changed.
|
||||
assert ts == ts.tz_convert(dateutil.tz.tzutc())
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Timestamp.__init__ with tz str or tzinfo
|
||||
|
||||
def test_timestamp_constructor_tz_utc(self):
|
||||
utc_stamp = Timestamp('3/11/2012 05:00', tz='utc')
|
||||
assert utc_stamp.tzinfo is pytz.utc
|
||||
assert utc_stamp.hour == 5
|
||||
|
||||
utc_stamp = Timestamp('3/11/2012 05:00').tz_localize('utc')
|
||||
assert utc_stamp.hour == 5
|
||||
|
||||
def test_timestamp_to_datetime_tzoffset(self):
|
||||
tzinfo = tzoffset(None, 7200)
|
||||
expected = Timestamp('3/11/2012 04:00', tz=tzinfo)
|
||||
result = Timestamp(expected.to_pydatetime())
|
||||
assert expected == result
|
||||
|
||||
def test_timestamp_constructor_near_dst_boundary(self):
|
||||
# GH#11481 & GH#15777
|
||||
# Naive string timestamps were being localized incorrectly
|
||||
# with tz_convert_single instead of tz_localize_to_utc
|
||||
|
||||
for tz in ['Europe/Brussels', 'Europe/Prague']:
|
||||
result = Timestamp('2015-10-25 01:00', tz=tz)
|
||||
expected = Timestamp('2015-10-25 01:00').tz_localize(tz)
|
||||
assert result == expected
|
||||
|
||||
with pytest.raises(pytz.AmbiguousTimeError):
|
||||
Timestamp('2015-10-25 02:00', tz=tz)
|
||||
|
||||
result = Timestamp('2017-03-26 01:00', tz='Europe/Paris')
|
||||
expected = Timestamp('2017-03-26 01:00').tz_localize('Europe/Paris')
|
||||
assert result == expected
|
||||
|
||||
with pytest.raises(pytz.NonExistentTimeError):
|
||||
Timestamp('2017-03-26 02:00', tz='Europe/Paris')
|
||||
|
||||
# GH#11708
|
||||
naive = Timestamp('2015-11-18 10:00:00')
|
||||
result = naive.tz_localize('UTC').tz_convert('Asia/Kolkata')
|
||||
expected = Timestamp('2015-11-18 15:30:00+0530', tz='Asia/Kolkata')
|
||||
assert result == expected
|
||||
|
||||
# GH#15823
|
||||
result = Timestamp('2017-03-26 00:00', tz='Europe/Paris')
|
||||
expected = Timestamp('2017-03-26 00:00:00+0100', tz='Europe/Paris')
|
||||
assert result == expected
|
||||
|
||||
result = Timestamp('2017-03-26 01:00', tz='Europe/Paris')
|
||||
expected = Timestamp('2017-03-26 01:00:00+0100', tz='Europe/Paris')
|
||||
assert result == expected
|
||||
|
||||
with pytest.raises(pytz.NonExistentTimeError):
|
||||
Timestamp('2017-03-26 02:00', tz='Europe/Paris')
|
||||
|
||||
result = Timestamp('2017-03-26 02:00:00+0100', tz='Europe/Paris')
|
||||
naive = Timestamp(result.value)
|
||||
expected = naive.tz_localize('UTC').tz_convert('Europe/Paris')
|
||||
assert result == expected
|
||||
|
||||
result = Timestamp('2017-03-26 03:00', tz='Europe/Paris')
|
||||
expected = Timestamp('2017-03-26 03:00:00+0200', tz='Europe/Paris')
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('tz', [pytz.timezone('US/Eastern'),
|
||||
gettz('US/Eastern'),
|
||||
'US/Eastern', 'dateutil/US/Eastern'])
|
||||
def test_timestamp_constructed_by_date_and_tz(self, tz):
|
||||
# GH#2993, Timestamp cannot be constructed by datetime.date
|
||||
# and tz correctly
|
||||
|
||||
result = Timestamp(date(2012, 3, 11), tz=tz)
|
||||
|
||||
expected = Timestamp('3/11/2012', tz=tz)
|
||||
assert result.hour == expected.hour
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('tz', [pytz.timezone('US/Eastern'),
|
||||
gettz('US/Eastern'),
|
||||
'US/Eastern', 'dateutil/US/Eastern'])
|
||||
def test_timestamp_add_timedelta_push_over_dst_boundary(self, tz):
|
||||
# GH#1389
|
||||
|
||||
# 4 hours before DST transition
|
||||
stamp = Timestamp('3/10/2012 22:00', tz=tz)
|
||||
|
||||
result = stamp + timedelta(hours=6)
|
||||
|
||||
# spring forward, + "7" hours
|
||||
expected = Timestamp('3/11/2012 05:00', tz=tz)
|
||||
|
||||
assert result == expected
|
||||
|
||||
def test_timestamp_timetz_equivalent_with_datetime_tz(self,
|
||||
tz_naive_fixture):
|
||||
# GH21358
|
||||
tz = timezones.maybe_get_tz(tz_naive_fixture)
|
||||
|
||||
stamp = Timestamp('2018-06-04 10:20:30', tz=tz)
|
||||
_datetime = datetime(2018, 6, 4, hour=10,
|
||||
minute=20, second=30, tzinfo=tz)
|
||||
|
||||
result = stamp.timetz()
|
||||
expected = _datetime.timetz()
|
||||
|
||||
assert result == expected
|
||||
+364
@@ -0,0 +1,364 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime
|
||||
|
||||
from dateutil.tz import gettz
|
||||
import pytest
|
||||
import pytz
|
||||
from pytz import utc
|
||||
|
||||
from pandas._libs.tslibs import conversion
|
||||
from pandas._libs.tslibs.frequencies import INVALID_FREQ_ERR_MSG
|
||||
from pandas.compat import PY3
|
||||
import pandas.util._test_decorators as td
|
||||
|
||||
from pandas import NaT, Timestamp
|
||||
import pandas.util.testing as tm
|
||||
|
||||
from pandas.tseries.frequencies import to_offset
|
||||
|
||||
|
||||
class TestTimestampUnaryOps(object):
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Timestamp.round
|
||||
@pytest.mark.parametrize('timestamp, freq, expected', [
|
||||
('20130101 09:10:11', 'D', '20130101'),
|
||||
('20130101 19:10:11', 'D', '20130102'),
|
||||
('20130201 12:00:00', 'D', '20130202'),
|
||||
('20130104 12:00:00', 'D', '20130105'),
|
||||
('2000-01-05 05:09:15.13', 'D', '2000-01-05 00:00:00'),
|
||||
('2000-01-05 05:09:15.13', 'H', '2000-01-05 05:00:00'),
|
||||
('2000-01-05 05:09:15.13', 'S', '2000-01-05 05:09:15')
|
||||
])
|
||||
def test_round_frequencies(self, timestamp, freq, expected):
|
||||
dt = Timestamp(timestamp)
|
||||
result = dt.round(freq)
|
||||
expected = Timestamp(expected)
|
||||
assert result == expected
|
||||
|
||||
def test_round_tzaware(self):
|
||||
dt = Timestamp('20130101 09:10:11', tz='US/Eastern')
|
||||
result = dt.round('D')
|
||||
expected = Timestamp('20130101', tz='US/Eastern')
|
||||
assert result == expected
|
||||
|
||||
dt = Timestamp('20130101 09:10:11', tz='US/Eastern')
|
||||
result = dt.round('s')
|
||||
assert result == dt
|
||||
|
||||
def test_round_30min(self):
|
||||
# round
|
||||
dt = Timestamp('20130104 12:32:00')
|
||||
result = dt.round('30Min')
|
||||
expected = Timestamp('20130104 12:30:00')
|
||||
assert result == expected
|
||||
|
||||
def test_round_subsecond(self):
|
||||
# GH#14440 & GH#15578
|
||||
result = Timestamp('2016-10-17 12:00:00.0015').round('ms')
|
||||
expected = Timestamp('2016-10-17 12:00:00.002000')
|
||||
assert result == expected
|
||||
|
||||
result = Timestamp('2016-10-17 12:00:00.00149').round('ms')
|
||||
expected = Timestamp('2016-10-17 12:00:00.001000')
|
||||
assert result == expected
|
||||
|
||||
ts = Timestamp('2016-10-17 12:00:00.0015')
|
||||
for freq in ['us', 'ns']:
|
||||
assert ts == ts.round(freq)
|
||||
|
||||
result = Timestamp('2016-10-17 12:00:00.001501031').round('10ns')
|
||||
expected = Timestamp('2016-10-17 12:00:00.001501030')
|
||||
assert result == expected
|
||||
|
||||
def test_round_nonstandard_freq(self):
|
||||
with tm.assert_produces_warning(False):
|
||||
Timestamp('2016-10-17 12:00:00.001501031').round('1010ns')
|
||||
|
||||
def test_round_invalid_arg(self):
|
||||
stamp = Timestamp('2000-01-05 05:09:15.13')
|
||||
with pytest.raises(ValueError, match=INVALID_FREQ_ERR_MSG):
|
||||
stamp.round('foo')
|
||||
|
||||
@pytest.mark.parametrize('test_input, rounder, freq, expected', [
|
||||
('2117-01-01 00:00:45', 'floor', '15s', '2117-01-01 00:00:45'),
|
||||
('2117-01-01 00:00:45', 'ceil', '15s', '2117-01-01 00:00:45'),
|
||||
('2117-01-01 00:00:45.000000012', 'floor', '10ns',
|
||||
'2117-01-01 00:00:45.000000010'),
|
||||
('1823-01-01 00:00:01.000000012', 'ceil', '10ns',
|
||||
'1823-01-01 00:00:01.000000020'),
|
||||
('1823-01-01 00:00:01', 'floor', '1s', '1823-01-01 00:00:01'),
|
||||
('1823-01-01 00:00:01', 'ceil', '1s', '1823-01-01 00:00:01'),
|
||||
('NaT', 'floor', '1s', 'NaT'),
|
||||
('NaT', 'ceil', '1s', 'NaT')
|
||||
])
|
||||
def test_ceil_floor_edge(self, test_input, rounder, freq, expected):
|
||||
dt = Timestamp(test_input)
|
||||
func = getattr(dt, rounder)
|
||||
result = func(freq)
|
||||
|
||||
if dt is NaT:
|
||||
assert result is NaT
|
||||
else:
|
||||
expected = Timestamp(expected)
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('test_input, freq, expected', [
|
||||
('2018-01-01 00:02:06', '2s', '2018-01-01 00:02:06'),
|
||||
('2018-01-01 00:02:00', '2T', '2018-01-01 00:02:00'),
|
||||
('2018-01-01 00:04:00', '4T', '2018-01-01 00:04:00'),
|
||||
('2018-01-01 00:15:00', '15T', '2018-01-01 00:15:00'),
|
||||
('2018-01-01 00:20:00', '20T', '2018-01-01 00:20:00'),
|
||||
('2018-01-01 03:00:00', '3H', '2018-01-01 03:00:00'),
|
||||
])
|
||||
@pytest.mark.parametrize('rounder', ['ceil', 'floor', 'round'])
|
||||
def test_round_minute_freq(self, test_input, freq, expected, rounder):
|
||||
# Ensure timestamps that shouldnt round dont!
|
||||
# GH#21262
|
||||
|
||||
dt = Timestamp(test_input)
|
||||
expected = Timestamp(expected)
|
||||
func = getattr(dt, rounder)
|
||||
result = func(freq)
|
||||
assert result == expected
|
||||
|
||||
def test_ceil(self):
|
||||
dt = Timestamp('20130101 09:10:11')
|
||||
result = dt.ceil('D')
|
||||
expected = Timestamp('20130102')
|
||||
assert result == expected
|
||||
|
||||
def test_floor(self):
|
||||
dt = Timestamp('20130101 09:10:11')
|
||||
result = dt.floor('D')
|
||||
expected = Timestamp('20130101')
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('method', ['ceil', 'round', 'floor'])
|
||||
def test_round_dst_border_ambiguous(self, method):
|
||||
# GH 18946 round near "fall back" DST
|
||||
ts = Timestamp('2017-10-29 00:00:00', tz='UTC').tz_convert(
|
||||
'Europe/Madrid'
|
||||
)
|
||||
#
|
||||
result = getattr(ts, method)('H', ambiguous=True)
|
||||
assert result == ts
|
||||
|
||||
result = getattr(ts, method)('H', ambiguous=False)
|
||||
expected = Timestamp('2017-10-29 01:00:00', tz='UTC').tz_convert(
|
||||
'Europe/Madrid'
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
result = getattr(ts, method)('H', ambiguous='NaT')
|
||||
assert result is NaT
|
||||
|
||||
with pytest.raises(pytz.AmbiguousTimeError):
|
||||
getattr(ts, method)('H', ambiguous='raise')
|
||||
|
||||
@pytest.mark.parametrize('method, ts_str, freq', [
|
||||
['ceil', '2018-03-11 01:59:00-0600', '5min'],
|
||||
['round', '2018-03-11 01:59:00-0600', '5min'],
|
||||
['floor', '2018-03-11 03:01:00-0500', '2H']])
|
||||
def test_round_dst_border_nonexistent(self, method, ts_str, freq):
|
||||
# GH 23324 round near "spring forward" DST
|
||||
ts = Timestamp(ts_str, tz='America/Chicago')
|
||||
result = getattr(ts, method)(freq, nonexistent='shift_forward')
|
||||
expected = Timestamp('2018-03-11 03:00:00', tz='America/Chicago')
|
||||
assert result == expected
|
||||
|
||||
result = getattr(ts, method)(freq, nonexistent='NaT')
|
||||
assert result is NaT
|
||||
|
||||
with pytest.raises(pytz.NonExistentTimeError,
|
||||
match='2018-03-11 02:00:00'):
|
||||
getattr(ts, method)(freq, nonexistent='raise')
|
||||
|
||||
@pytest.mark.parametrize('timestamp', [
|
||||
'2018-01-01 0:0:0.124999360',
|
||||
'2018-01-01 0:0:0.125000367',
|
||||
'2018-01-01 0:0:0.125500',
|
||||
'2018-01-01 0:0:0.126500',
|
||||
'2018-01-01 12:00:00',
|
||||
'2019-01-01 12:00:00',
|
||||
])
|
||||
@pytest.mark.parametrize('freq', [
|
||||
'2ns', '3ns', '4ns', '5ns', '6ns', '7ns',
|
||||
'250ns', '500ns', '750ns',
|
||||
'1us', '19us', '250us', '500us', '750us',
|
||||
'1s', '2s', '3s',
|
||||
'1D',
|
||||
])
|
||||
def test_round_int64(self, timestamp, freq):
|
||||
"""check that all rounding modes are accurate to int64 precision
|
||||
see GH#22591
|
||||
"""
|
||||
dt = Timestamp(timestamp)
|
||||
unit = to_offset(freq).nanos
|
||||
|
||||
# test floor
|
||||
result = dt.floor(freq)
|
||||
assert result.value % unit == 0, "floor not a {} multiple".format(freq)
|
||||
assert 0 <= dt.value - result.value < unit, "floor error"
|
||||
|
||||
# test ceil
|
||||
result = dt.ceil(freq)
|
||||
assert result.value % unit == 0, "ceil not a {} multiple".format(freq)
|
||||
assert 0 <= result.value - dt.value < unit, "ceil error"
|
||||
|
||||
# test round
|
||||
result = dt.round(freq)
|
||||
assert result.value % unit == 0, "round not a {} multiple".format(freq)
|
||||
assert abs(result.value - dt.value) <= unit // 2, "round error"
|
||||
if unit % 2 == 0 and abs(result.value - dt.value) == unit // 2:
|
||||
# round half to even
|
||||
assert result.value // unit % 2 == 0, "round half to even error"
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Timestamp.replace
|
||||
|
||||
def test_replace_naive(self):
|
||||
# GH#14621, GH#7825
|
||||
ts = Timestamp('2016-01-01 09:00:00')
|
||||
result = ts.replace(hour=0)
|
||||
expected = Timestamp('2016-01-01 00:00:00')
|
||||
assert result == expected
|
||||
|
||||
def test_replace_aware(self, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
# GH#14621, GH#7825
|
||||
# replacing datetime components with and w/o presence of a timezone
|
||||
ts = Timestamp('2016-01-01 09:00:00', tz=tz)
|
||||
result = ts.replace(hour=0)
|
||||
expected = Timestamp('2016-01-01 00:00:00', tz=tz)
|
||||
assert result == expected
|
||||
|
||||
def test_replace_preserves_nanos(self, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
# GH#14621, GH#7825
|
||||
ts = Timestamp('2016-01-01 09:00:00.000000123', tz=tz)
|
||||
result = ts.replace(hour=0)
|
||||
expected = Timestamp('2016-01-01 00:00:00.000000123', tz=tz)
|
||||
assert result == expected
|
||||
|
||||
def test_replace_multiple(self, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
# GH#14621, GH#7825
|
||||
# replacing datetime components with and w/o presence of a timezone
|
||||
# test all
|
||||
ts = Timestamp('2016-01-01 09:00:00.000000123', tz=tz)
|
||||
result = ts.replace(year=2015, month=2, day=2, hour=0, minute=5,
|
||||
second=5, microsecond=5, nanosecond=5)
|
||||
expected = Timestamp('2015-02-02 00:05:05.000005005', tz=tz)
|
||||
assert result == expected
|
||||
|
||||
def test_replace_invalid_kwarg(self, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
# GH#14621, GH#7825
|
||||
ts = Timestamp('2016-01-01 09:00:00.000000123', tz=tz)
|
||||
with pytest.raises(TypeError):
|
||||
ts.replace(foo=5)
|
||||
|
||||
def test_replace_integer_args(self, tz_aware_fixture):
|
||||
tz = tz_aware_fixture
|
||||
# GH#14621, GH#7825
|
||||
ts = Timestamp('2016-01-01 09:00:00.000000123', tz=tz)
|
||||
with pytest.raises(ValueError):
|
||||
ts.replace(hour=0.1)
|
||||
|
||||
def test_replace_tzinfo_equiv_tz_localize_none(self):
|
||||
# GH#14621, GH#7825
|
||||
# assert conversion to naive is the same as replacing tzinfo with None
|
||||
ts = Timestamp('2013-11-03 01:59:59.999999-0400', tz='US/Eastern')
|
||||
assert ts.tz_localize(None) == ts.replace(tzinfo=None)
|
||||
|
||||
@td.skip_if_windows
|
||||
def test_replace_tzinfo(self):
|
||||
# GH#15683
|
||||
dt = datetime(2016, 3, 27, 1)
|
||||
tzinfo = pytz.timezone('CET').localize(dt, is_dst=False).tzinfo
|
||||
|
||||
result_dt = dt.replace(tzinfo=tzinfo)
|
||||
result_pd = Timestamp(dt).replace(tzinfo=tzinfo)
|
||||
|
||||
if PY3:
|
||||
# datetime.timestamp() converts in the local timezone
|
||||
with tm.set_timezone('UTC'):
|
||||
assert result_dt.timestamp() == result_pd.timestamp()
|
||||
|
||||
assert result_dt == result_pd
|
||||
assert result_dt == result_pd.to_pydatetime()
|
||||
|
||||
result_dt = dt.replace(tzinfo=tzinfo).replace(tzinfo=None)
|
||||
result_pd = Timestamp(dt).replace(tzinfo=tzinfo).replace(tzinfo=None)
|
||||
|
||||
if PY3:
|
||||
# datetime.timestamp() converts in the local timezone
|
||||
with tm.set_timezone('UTC'):
|
||||
assert result_dt.timestamp() == result_pd.timestamp()
|
||||
|
||||
assert result_dt == result_pd
|
||||
assert result_dt == result_pd.to_pydatetime()
|
||||
|
||||
@pytest.mark.parametrize('tz, normalize', [
|
||||
(pytz.timezone('US/Eastern'), lambda x: x.tzinfo.normalize(x)),
|
||||
(gettz('US/Eastern'), lambda x: x)])
|
||||
def test_replace_across_dst(self, tz, normalize):
|
||||
# GH#18319 check that 1) timezone is correctly normalized and
|
||||
# 2) that hour is not incorrectly changed by this normalization
|
||||
ts_naive = Timestamp('2017-12-03 16:03:30')
|
||||
ts_aware = conversion.localize_pydatetime(ts_naive, tz)
|
||||
|
||||
# Preliminary sanity-check
|
||||
assert ts_aware == normalize(ts_aware)
|
||||
|
||||
# Replace across DST boundary
|
||||
ts2 = ts_aware.replace(month=6)
|
||||
|
||||
# Check that `replace` preserves hour literal
|
||||
assert (ts2.hour, ts2.minute) == (ts_aware.hour, ts_aware.minute)
|
||||
|
||||
# Check that post-replace object is appropriately normalized
|
||||
ts2b = normalize(ts2)
|
||||
assert ts2 == ts2b
|
||||
|
||||
def test_replace_dst_border(self):
|
||||
# Gh 7825
|
||||
t = Timestamp('2013-11-3', tz='America/Chicago')
|
||||
result = t.replace(hour=3)
|
||||
expected = Timestamp('2013-11-3 03:00:00', tz='America/Chicago')
|
||||
assert result == expected
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Timestamp.normalize
|
||||
|
||||
@pytest.mark.parametrize('arg', ['2013-11-30', '2013-11-30 12:00:00'])
|
||||
def test_normalize(self, tz_naive_fixture, arg):
|
||||
tz = tz_naive_fixture
|
||||
ts = Timestamp(arg, tz=tz)
|
||||
result = ts.normalize()
|
||||
expected = Timestamp('2013-11-30', tz=tz)
|
||||
assert result == expected
|
||||
|
||||
# --------------------------------------------------------------
|
||||
|
||||
@td.skip_if_windows
|
||||
def test_timestamp(self):
|
||||
# GH#17329
|
||||
# tz-naive --> treat it as if it were UTC for purposes of timestamp()
|
||||
ts = Timestamp.now()
|
||||
uts = ts.replace(tzinfo=utc)
|
||||
assert ts.timestamp() == uts.timestamp()
|
||||
|
||||
tsc = Timestamp('2014-10-11 11:00:01.12345678', tz='US/Central')
|
||||
utsc = tsc.tz_convert('UTC')
|
||||
|
||||
# utsc is a different representation of the same time
|
||||
assert tsc.timestamp() == utsc.timestamp()
|
||||
|
||||
if PY3:
|
||||
# datetime.timestamp() converts in the local timezone
|
||||
with tm.set_timezone('UTC'):
|
||||
# should agree with datetime.timestamp method
|
||||
dt = ts.to_pydatetime()
|
||||
assert dt.timestamp() == ts.timestamp()
|
||||
Reference in New Issue
Block a user