Skip to content

Commit 65adecf

Browse files
author
Chang She
committed
BUG: week of year incorrect at year boundaries pandas-dev#2768
1 parent c34c4f0 commit 65adecf

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

pandas/tseries/tests/test_timeseries.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def test_indexing(self):
205205

206206
# GH 3070, make sure semantics work on Series/Frame
207207
expected = ts['2001']
208-
208+
209209
df = DataFrame(dict(A = ts))
210210
result = df['2001']['A']
211211
assert_series_equal(expected,result)
@@ -1232,7 +1232,6 @@ def test_frame_to_period(self):
12321232

12331233
def test_timestamp_fields(self):
12341234
# extra fields from DatetimeIndex like quarter and week
1235-
from pandas.lib import Timestamp
12361235
idx = tm.makeDateIndex(100)
12371236

12381237
fields = ['dayofweek', 'dayofyear', 'week', 'weekofyear', 'quarter']
@@ -1244,6 +1243,33 @@ def test_timestamp_fields(self):
12441243
self.assertEqual(idx.freq, Timestamp(idx[-1], idx.freq).freq)
12451244
self.assertEqual(idx.freqstr, Timestamp(idx[-1], idx.freq).freqstr)
12461245

1246+
def test_woy_boundary(self):
1247+
# make sure weeks at year boundaries are correct
1248+
d = datetime(2013,12,31)
1249+
result = Timestamp(d).week
1250+
expected = 1 # ISO standard
1251+
self.assertEqual(result, expected)
1252+
1253+
d = datetime(2008,12,28)
1254+
result = Timestamp(d).week
1255+
expected = 52 # ISO standard
1256+
self.assertEqual(result, expected)
1257+
1258+
d = datetime(2009,12,31)
1259+
result = Timestamp(d).week
1260+
expected = 53 # ISO standard
1261+
self.assertEqual(result, expected)
1262+
1263+
d = datetime(2010,1,1)
1264+
result = Timestamp(d).week
1265+
expected = 53 # ISO standard
1266+
self.assertEqual(result, expected)
1267+
1268+
d = datetime(2010,1,3)
1269+
result = Timestamp(d).week
1270+
expected = 53 # ISO standard
1271+
self.assertEqual(result, expected)
1272+
12471273
def test_timestamp_date_out_of_range(self):
12481274
self.assertRaises(ValueError, Timestamp, '1676-01-01')
12491275
self.assertRaises(ValueError, Timestamp, '2263-01-01')

pandas/tslib.pyx

+22-2
Original file line numberDiff line numberDiff line change
@@ -1668,6 +1668,7 @@ def get_date_field(ndarray[int64_t] dtindex, object field):
16681668
ndarray[int32_t, ndim=2] _month_offset
16691669
int isleap
16701670
pandas_datetimestruct dts
1671+
int mo_off, doy, dow, woy
16711672

16721673
_month_offset = np.array(
16731674
[[ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 ],
@@ -1761,9 +1762,28 @@ def get_date_field(ndarray[int64_t] dtindex, object field):
17611762
if dtindex[i] == NPY_NAT: out[i] = -1; continue
17621763

17631764
pandas_datetime_to_datetimestruct(dtindex[i], PANDAS_FR_ns, &dts)
1765+
ts = convert_to_tsobject(dtindex[i], None)
17641766
isleap = is_leapyear(dts.year)
1765-
out[i] = _month_offset[isleap, dts.month - 1] + dts.day
1766-
out[i] = ((out[i] - 1) / 7) + 1
1767+
mo_off = _month_offset[isleap, dts.month - 1]
1768+
doy = mo_off + dts.day
1769+
dow = ts_dayofweek(ts)
1770+
1771+
#estimate
1772+
woy = (doy - 1) - dow + 3
1773+
if woy >= 0:
1774+
woy = woy / 7 + 1
1775+
1776+
# verify
1777+
if woy < 0:
1778+
if (woy > -2) or (woy == -2 and isleap):
1779+
woy = 53
1780+
else:
1781+
woy = 52
1782+
elif woy == 53:
1783+
if 31 - dts.day + dow < 3:
1784+
woy = 1
1785+
1786+
out[i] = woy
17671787
return out
17681788

17691789
elif field == 'q':

0 commit comments

Comments
 (0)