@@ -115,6 +115,9 @@ class DatetimeIndex(Int64Index):
115115 end : end time, datetime-like, optional
116116 If periods is none, generated index will extend to first conforming
117117 time on or just past end argument
118+ closed : string or None, default None
119+ Make the interval closed with respect to the given frequency to
120+ the 'left', 'right', or both sides (None)
118121 """
119122 _join_precedence = 10
120123
@@ -143,7 +146,8 @@ class DatetimeIndex(Int64Index):
143146 def __new__ (cls , data = None ,
144147 freq = None , start = None , end = None , periods = None ,
145148 copy = False , name = None , tz = None ,
146- verify_integrity = True , normalize = False , ** kwds ):
149+ verify_integrity = True , normalize = False ,
150+ closed = None , ** kwds ):
147151
148152 dayfirst = kwds .pop ('dayfirst' , None )
149153 yearfirst = kwds .pop ('yearfirst' , None )
@@ -184,7 +188,7 @@ def __new__(cls, data=None,
184188
185189 if data is None :
186190 return cls ._generate (start , end , periods , name , offset ,
187- tz = tz , normalize = normalize ,
191+ tz = tz , normalize = normalize , closed = closed ,
188192 infer_dst = infer_dst )
189193
190194 if not isinstance (data , np .ndarray ):
@@ -289,7 +293,7 @@ def __new__(cls, data=None,
289293
290294 @classmethod
291295 def _generate (cls , start , end , periods , name , offset ,
292- tz = None , normalize = False , infer_dst = False ):
296+ tz = None , normalize = False , infer_dst = False , closed = None ):
293297 if com ._count_not_none (start , end , periods ) != 2 :
294298 raise ValueError ('Must specify two of start, end, or periods' )
295299
@@ -301,6 +305,24 @@ def _generate(cls, start, end, periods, name, offset,
301305 if end is not None :
302306 end = Timestamp (end )
303307
308+ left_closed = False
309+ right_closed = False
310+
311+ if start is None and end is None :
312+ if closed is not None :
313+ raise ValueError ("Closed has to be None if not both of start"
314+ "and end are defined" )
315+
316+ if closed is None :
317+ left_closed = True
318+ right_closed = True
319+ elif closed == "left" :
320+ left_closed = True
321+ elif closed == "right" :
322+ right_closed = True
323+ else :
324+ raise ValueError ("Closed has to be either 'left', 'right' or None" )
325+
304326 try :
305327 inferred_tz = tools ._infer_tzinfo (start , end )
306328 except :
@@ -387,6 +409,11 @@ def _generate(cls, start, end, periods, name, offset,
387409 index .offset = offset
388410 index .tz = tz
389411
412+ if not left_closed :
413+ index = index [1 :]
414+ if not right_closed :
415+ index = index [:- 1 ]
416+
390417 return index
391418
392419 def _box_values (self , values ):
@@ -1715,7 +1742,7 @@ def _generate_regular_range(start, end, periods, offset):
17151742
17161743
17171744def date_range (start = None , end = None , periods = None , freq = 'D' , tz = None ,
1718- normalize = False , name = None ):
1745+ normalize = False , name = None , closed = None ):
17191746 """
17201747 Return a fixed frequency datetime index, with day (calendar) as the default
17211748 frequency
@@ -1737,6 +1764,9 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None,
17371764 Normalize start/end dates to midnight before generating date range
17381765 name : str, default None
17391766 Name of the resulting index
1767+ closed : string or None, default None
1768+ Make the interval closed with respect to the given frequency to
1769+ the 'left', 'right', or both sides (None)
17401770
17411771 Notes
17421772 -----
@@ -1747,11 +1777,12 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None,
17471777 rng : DatetimeIndex
17481778 """
17491779 return DatetimeIndex (start = start , end = end , periods = periods ,
1750- freq = freq , tz = tz , normalize = normalize , name = name )
1780+ freq = freq , tz = tz , normalize = normalize , name = name ,
1781+ closed = closed )
17511782
17521783
17531784def bdate_range (start = None , end = None , periods = None , freq = 'B' , tz = None ,
1754- normalize = True , name = None ):
1785+ normalize = True , name = None , closed = None ):
17551786 """
17561787 Return a fixed frequency datetime index, with business day as the default
17571788 frequency
@@ -1773,6 +1804,9 @@ def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
17731804 Normalize start/end dates to midnight before generating date range
17741805 name : str, default None
17751806 Name for the resulting index
1807+ closed : string or None, default None
1808+ Make the interval closed with respect to the given frequency to
1809+ the 'left', 'right', or both sides (None)
17761810
17771811 Notes
17781812 -----
@@ -1784,11 +1818,12 @@ def bdate_range(start=None, end=None, periods=None, freq='B', tz=None,
17841818 """
17851819
17861820 return DatetimeIndex (start = start , end = end , periods = periods ,
1787- freq = freq , tz = tz , normalize = normalize , name = name )
1821+ freq = freq , tz = tz , normalize = normalize , name = name ,
1822+ closed = closed )
17881823
17891824
17901825def cdate_range (start = None , end = None , periods = None , freq = 'C' , tz = None ,
1791- normalize = True , name = None , ** kwargs ):
1826+ normalize = True , name = None , closed = None , ** kwargs ):
17921827 """
17931828 **EXPERIMENTAL** Return a fixed frequency datetime index, with
17941829 CustomBusinessDay as the default frequency
@@ -1820,6 +1855,9 @@ def cdate_range(start=None, end=None, periods=None, freq='C', tz=None,
18201855 holidays : list
18211856 list/array of dates to exclude from the set of valid business days,
18221857 passed to ``numpy.busdaycalendar``
1858+ closed : string or None, default None
1859+ Make the interval closed with respect to the given frequency to
1860+ the 'left', 'right', or both sides (None)
18231861
18241862 Notes
18251863 -----
@@ -1835,7 +1873,8 @@ def cdate_range(start=None, end=None, periods=None, freq='C', tz=None,
18351873 weekmask = kwargs .pop ('weekmask' , 'Mon Tue Wed Thu Fri' )
18361874 freq = CDay (holidays = holidays , weekmask = weekmask )
18371875 return DatetimeIndex (start = start , end = end , periods = periods , freq = freq ,
1838- tz = tz , normalize = normalize , name = name , ** kwargs )
1876+ tz = tz , normalize = normalize , name = name ,
1877+ closed = closed , ** kwargs )
18391878
18401879
18411880def _to_m8 (key , tz = None ):
0 commit comments