Repository: pandas-dev/pandas

Issue:
DateFrame.truncate is not equivalent to slicing as mentioned in docs
#### Code Sample, a copy-pastable example if possible

```python
>>> index = pd.date_range('2016-1-1', '2016-2-1', freq='s')
>>> df = pd.DataFrame(index=d, data={'a':1})  
>>> df.loc['2016-1-5 05':'2016-1-10']                  
                     a
2016-01-05 00:00:00  1
2016-01-05 00:00:01  1
2016-01-05 00:00:02  1
...
2016-01-10 23:59:57  1
2016-01-10 23:59:58  1
2016-01-10 23:59:59  1

>>> df.truncate('2016-1-5', '2016-1-10')
                     a
2016-01-05 00:00:00  1
2016-01-05 00:00:01  1
2016-01-05 00:00:02  1
...
2016-01-09 23:59:58  1
2016-01-09 23:59:59  1
2016-01-10 00:00:00  1
```
#### Problem description
The [documentation](http://pandas.pydata.org/pandas-docs/stable/timeseries.html#truncating-fancy-indexing) for `truncate` has misleading information. `truncate` and slicing are not the same. Slicing returns all partially matching dates while truncate stops at an exact datetime - it assumes 0's for any unspecified date component.

Also, truncate can take datetime and partial string datetimes which, to me, isn't apparent in the docstrings.

#### Expected Output

#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------
commit: None
python: 3.6.1.final.0
python-bits: 64
OS: Darwin
OS-release: 15.6.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.20.3
pytest: 3.0.7
pip: 9.0.1
setuptools: 35.0.2
Cython: 0.25.2
numpy: 1.13.1
scipy: 0.19.0
xarray: None
IPython: 6.0.0
sphinx: 1.5.5
patsy: 0.4.1
dateutil: 2.6.1
pytz: 2017.2
blosc: None
bottleneck: 1.2.0
tables: 3.4.2
numexpr: 2.6.2
feather: None
matplotlib: 2.0.2
openpyxl: 2.4.7
xlrd: 1.0.0
xlwt: 1.2.0
xlsxwriter: 0.9.6
lxml: 3.7.3
bs4: 4.6.0
html5lib: 0.9999999
sqlalchemy: 1.1.9
pymysql: None
psycopg2: None
jinja2: 2.9.6
s3fs: None
pandas_gbq: None
pandas_datareader: 0.3.0.post

</details>



Discussion:
The docstring can indeed use some love (and examples). PR's welcome.

That said, we could also question the need for this function. Is it that useful given you can do the same with indexing? (if you are aware of the difference in how the labels are interpreted) 

Just as a question (I never use it myself), do you use this function a lot? And if so, would it be hard to convert to using slicing?

I've never used it and it seems to rarely come up on stackoverflow. 

I suppose it could be useful to add parameters include_start and include_end like `between_time` but even then I'm not sure there is an example that would necessitate it over slicing.

At a more macro-scale, I find it strange that there are several DataFrame/Series methods that only work with DatetimeIndex - `first`, `last`, `truncate`, `between_time`, `at_time`, `as_freq`, `asof` and probably more that I can't think of at the moment.

The naming of some of these methods is completely non-intuitive. Especially something like `first/last` which have `groupby` methods of the same name (that are intuitive).

It would take a major break in API to refactor these methods out somewhere else.

Resolving patch:
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -6324,23 +6324,72 @@ def tshift(self, periods=1, freq=None, axis=0):
         return self._constructor(new_data).__finalize__(self)
 
     def truncate(self, before=None, after=None, axis=None, copy=True):
-        """Truncates a sorted NDFrame before and/or after some particular
-        index value. If the axis contains only datetime values, before/after
-        parameters are converted to datetime values.
+        """
+        Truncates a sorted DataFrame/Series before and/or after some
+        particular index value. If the axis contains only datetime values,
+        before/after parameters are converted to datetime values.
 
         Parameters
         ----------
-        before : date
-            Truncate before index value
-        after : date
-            Truncate after index value
-        axis : the truncation axis, defaults to the stat axis
+        before : date, string, int
+            Truncate all rows before this index value
+        after : date, string, int
+            Truncate all rows after this index value
+        axis : {0 or 'index', 1 or 'columns'}
+
+            * 0 or 'index': apply truncation to rows
+            * 1 or 'columns': apply truncation to columns
+            Default is stat axis for given data type (0 for Series and
+            DataFrames, 1 for Panels)
         copy : boolean, default is True,
             return a copy of the truncated section
 
         Returns
         -------
         truncated : type of caller
+
+        Examples
+        --------
+        >>> df = pd.DataFrame({'A': ['a', 'b', 'c', 'd', 'e'],
+        ...                    'B': ['f', 'g', 'h', 'i', 'j'],
+        ...                    'C': ['k', 'l', 'm', 'n', 'o']},
+        ...                    index=[1, 2, 3, 4, 5])
+        >>> df.truncate(before=2, after=4)
+           A  B  C
+        2  b  g  l
+        3  c  h  m
+        4  d  i  n
+        >>> df = pd.DataFrame({'A': [1, 2, 3, 4, 5],
+        ...                    'B': [6, 7, 8, 9, 10],
+        ...                    'C': [11, 12, 13, 14, 15]},
+        ...                    index=['a', 'b', 'c', 'd', 'e'])
+        >>> df.truncate(before='b', after='d')
+           A  B   C
+        b  2  7  12
+        c  3  8  13
+        d  4  9  14
+
+        The index values in ``truncate`` can be datetimes or string
+        dates. Note that ``truncate`` assumes a 0 value for any unspecified
+        date component in a ``DatetimeIndex`` in contrast to slicing which
+        returns any partially matching dates.
+
+        >>> dates = pd.date_range('2016-01-01', '2016-02-01', freq='s')
+        >>> df = pd.DataFrame(index=dates, data={'A': 1})
+        >>> df.truncate('2016-01-05', '2016-01-10').tail()
+                             A
+        2016-01-09 23:59:56  1
+        2016-01-09 23:59:57  1
+        2016-01-09 23:59:58  1
+        2016-01-09 23:59:59  1
+        2016-01-10 00:00:00  1
+        >>> df.loc['2016-01-05':'2016-01-10', :].tail()
+                             A
+        2016-01-10 23:59:55  1
+        2016-01-10 23:59:56  1
+        2016-01-10 23:59:57  1
+        2016-01-10 23:59:58  1
+        2016-01-10 23:59:59  1
         """
 
         if axis is None:


Test patch: