Repository: pandas-dev/pandas

Issue:
BUG: Possible BMonthEnd()
``` python
>>> import datetime as dt
>>> from pandas.tseries.offsets import *
>>> d = dt.datetime(2013, 6, 27, 8, 10)
>>> d + BMonthEnd()
datetime.datetime(2013, 6, 28, 0, 0) # correct!!!
>>> d = dt.datetime(2013, 6, 28, 8, 10)
>>> d + BMonthEnd()
datetime.datetime(2013, 7, 31, 0, 0) ## should 6/28 not 7/31...day not over
```



Discussion:
```
In [17]: d
Out[17]: datetime.datetime(2013, 6, 28, 8, 10)

In [18]: d + BDay()
Out[18]: Timestamp('2013-07-01 08:10:00')

In [19]: d + BDay(0)
Out[19]: Timestamp('2013-06-28 08:10:00')

In [20]: d + BMonthEnd(0)
Out[20]: Timestamp('2013-06-28 00:00:00')

In [21]: d + BMonthEnd(1)
Out[21]: datetime.datetime(2013, 7, 31, 0, 0)
```

I think this is correct, it is advancing to the _next_ month end (you can specify 0 if you don't want that).

exposed a different issue though, this should be returning Timestamps.....


Resolving patch:
diff --git a/pandas/tseries/offsets.py b/pandas/tseries/offsets.py
--- a/pandas/tseries/offsets.py
+++ b/pandas/tseries/offsets.py
@@ -472,9 +472,9 @@ def _set_busdaycalendar(self):
             kwargs = {'weekmask':self.weekmask,'holidays':self.holidays}
         else:
             kwargs = {'weekmask':self.weekmask}
-        try: 
+        try:
             self.busdaycalendar = np.busdaycalendar(**kwargs)
-        except: 
+        except:
             # Check we have the required numpy version
             from distutils.version import LooseVersion
 
@@ -484,9 +484,9 @@ def _set_busdaycalendar(self):
                                           np.__version__)
             else:
                 raise
-            
+
     def __getstate__(self):
-        """"Return a pickleable state"""
+        """Return a pickleable state"""
         state = self.__dict__.copy()
         del state['busdaycalendar']
         return state
@@ -520,7 +520,7 @@ def apply(self, other):
             if self.offset:
                 result = result + self.offset
 
-            return result
+            return as_timestamp(result)
 
         elif isinstance(other, np.datetime64):
             dtype = other.dtype
@@ -539,7 +539,7 @@ def apply(self, other):
             if self.offset:
                 result = result + self.offset
 
-            return result
+            return as_timestamp(result)
 
         elif isinstance(other, (timedelta, Tick)):
             return BDay(self.n, offset=self.offset + other,
@@ -639,7 +639,7 @@ def apply(self, other):
 
         if other.weekday() > 4:
             other = other - BDay()
-        return other
+        return as_timestamp(other)
 
     _prefix = 'BM'
 
@@ -706,7 +706,7 @@ def isAnchored(self):
 
     def apply(self, other):
         if self.weekday is None:
-            return as_datetime(other) + self.n * self._inc
+            return as_timestamp(as_datetime(other) + self.n * self._inc)
 
         if self.n > 0:
             k = self.n
@@ -998,7 +998,7 @@ def apply(self, other):
         if other.weekday() > 4:
             other = other - BDay()
 
-        return other
+        return as_timestamp(other)
 
     def onOffset(self, dt):
         modMonth = (dt.month - self.startingMonth) % 3
@@ -1188,7 +1188,7 @@ def apply(self, other):
         if result.weekday() > 4:
             result = result - BDay()
 
-        return result
+        return as_timestamp(result)
 
 
 class BYearBegin(YearOffset):


Test patch:
diff --git a/pandas/tseries/tests/test_offsets.py b/pandas/tseries/tests/test_offsets.py
--- a/pandas/tseries/tests/test_offsets.py
+++ b/pandas/tseries/tests/test_offsets.py
@@ -99,7 +99,7 @@ class TestBase(tm.TestCase):
 
     def test_apply_out_of_range(self):
         if self._offset is None:
-            raise nose.SkipTest("_offset not defined")
+            raise nose.SkipTest("_offset not defined to test out-of-range")
 
         # try to create an out-of-bounds result timestamp; if we can't create the offset
         # skip
@@ -113,6 +113,17 @@ def test_apply_out_of_range(self):
         except (ValueError, KeyError):
             raise nose.SkipTest("cannot create out_of_range offset")
 
+    def test_return_type(self):
+
+        # make sure that we are returning a Timestamp
+        try:
+            offset = self._offset(1)
+        except:
+            raise nose.SkipTest("_offset not defined to test return_type")
+
+        result = Timestamp('20080101') + offset
+        self.assertIsInstance(result, Timestamp)
+
 class TestDateOffset(TestBase):
     _multiprocess_can_split_ = True