18
18
from pandas ._libs .tslibs .offsets import (
19
19
ApplyTypeError ,
20
20
as_datetime , _is_normalized ,
21
- _get_firstbday , _get_calendar , _to_dt64 , _validate_business_time ,
21
+ get_firstbday , get_lastbday ,
22
+ _get_calendar , _to_dt64 , _validate_business_time ,
22
23
_int_to_weekday , _weekday_to_int ,
23
24
_determine_offset ,
24
25
apply_index_wraps ,
@@ -1181,18 +1182,14 @@ class BusinessMonthEnd(MonthOffset):
1181
1182
def apply (self , other ):
1182
1183
n = self .n
1183
1184
wkday , days_in_month = tslib .monthrange (other .year , other .month )
1184
- lastBDay = days_in_month - max (((wkday + days_in_month - 1 )
1185
- % 7 ) - 4 , 0 )
1185
+ lastBDay = get_lastbday (wkday , days_in_month )
1186
1186
1187
1187
if n > 0 and not other .day >= lastBDay :
1188
1188
n = n - 1
1189
1189
elif n <= 0 and other .day > lastBDay :
1190
1190
n = n + 1
1191
- other = shift_month (other , n , 'end' )
1192
1191
1193
- if other .weekday () > 4 :
1194
- other = other - BDay ()
1195
- return other
1192
+ return shift_month (other , n , 'business_end' )
1196
1193
1197
1194
1198
1195
class BusinessMonthBegin (MonthOffset ):
@@ -1203,7 +1200,7 @@ class BusinessMonthBegin(MonthOffset):
1203
1200
def apply (self , other ):
1204
1201
n = self .n
1205
1202
wkday , _ = tslib .monthrange (other .year , other .month )
1206
- first = _get_firstbday (wkday )
1203
+ first = get_firstbday (wkday )
1207
1204
1208
1205
if other .day > first and n <= 0 :
1209
1206
# as if rolled forward already
@@ -1212,24 +1209,13 @@ def apply(self, other):
1212
1209
other = other + timedelta (days = first - other .day )
1213
1210
n -= 1
1214
1211
1215
- other = shift_month (other , n , None )
1216
- wkday , _ = tslib .monthrange (other .year , other .month )
1217
- first = _get_firstbday (wkday )
1218
- result = datetime (other .year , other .month , first ,
1219
- other .hour , other .minute ,
1220
- other .second , other .microsecond )
1221
- return result
1212
+ return shift_month (other , n , 'business_start' )
1222
1213
1223
1214
def onOffset (self , dt ):
1224
1215
if self .normalize and not _is_normalized (dt ):
1225
1216
return False
1226
1217
first_weekday , _ = tslib .monthrange (dt .year , dt .month )
1227
- if first_weekday == 5 :
1228
- return dt .day == 3
1229
- elif first_weekday == 6 :
1230
- return dt .day == 2
1231
- else :
1232
- return dt .day == 1
1218
+ return dt .day == get_firstbday (first_weekday )
1233
1219
1234
1220
1235
1221
class CustomBusinessMonthEnd (BusinessMixin , MonthOffset ):
@@ -1611,10 +1597,7 @@ def _from_name(cls, suffix=None):
1611
1597
1612
1598
class QuarterOffset (DateOffset ):
1613
1599
"""Quarter representation - doesn't call super"""
1614
-
1615
- #: default month for __init__
1616
1600
_default_startingMonth = None
1617
- #: default month in _from_name
1618
1601
_from_name_startingMonth = None
1619
1602
_adjust_dst = True
1620
1603
# TODO: Consider combining QuarterOffset and YearOffset __init__ at some
@@ -1656,21 +1639,15 @@ class BQuarterEnd(QuarterOffset):
1656
1639
"""
1657
1640
_outputName = 'BusinessQuarterEnd'
1658
1641
_default_startingMonth = 3
1659
- # 'BQ'
1660
1642
_from_name_startingMonth = 12
1661
1643
_prefix = 'BQ'
1662
1644
1663
1645
@apply_wraps
1664
1646
def apply (self , other ):
1665
1647
n = self .n
1666
- base = other
1667
- other = datetime (other .year , other .month , other .day ,
1668
- other .hour , other .minute , other .second ,
1669
- other .microsecond )
1670
1648
1671
1649
wkday , days_in_month = tslib .monthrange (other .year , other .month )
1672
- lastBDay = days_in_month - max (((wkday + days_in_month - 1 )
1673
- % 7 ) - 4 , 0 )
1650
+ lastBDay = get_lastbday (wkday , days_in_month )
1674
1651
1675
1652
monthsToGo = 3 - ((other .month - self .startingMonth ) % 3 )
1676
1653
if monthsToGo == 3 :
@@ -1681,11 +1658,7 @@ def apply(self, other):
1681
1658
elif n <= 0 and other .day > lastBDay and monthsToGo == 0 :
1682
1659
n = n + 1
1683
1660
1684
- other = shift_month (other , monthsToGo + 3 * n , 'end' )
1685
- other = tslib ._localize_pydatetime (other , base .tzinfo )
1686
- if other .weekday () > 4 :
1687
- other = other - BDay ()
1688
- return other
1661
+ return shift_month (other , monthsToGo + 3 * n , 'business_end' )
1689
1662
1690
1663
def onOffset (self , dt ):
1691
1664
if self .normalize and not _is_normalized (dt ):
@@ -1711,7 +1684,7 @@ def apply(self, other):
1711
1684
n = self .n
1712
1685
wkday , _ = tslib .monthrange (other .year , other .month )
1713
1686
1714
- first = _get_firstbday (wkday )
1687
+ first = get_firstbday (wkday )
1715
1688
1716
1689
monthsSince = (other .month - self .startingMonth ) % 3
1717
1690
@@ -1725,14 +1698,7 @@ def apply(self, other):
1725
1698
elif n > 0 and (monthsSince == 0 and other .day < first ):
1726
1699
n = n - 1
1727
1700
1728
- # get the first bday for result
1729
- other = shift_month (other , 3 * n - monthsSince , None )
1730
- wkday , _ = tslib .monthrange (other .year , other .month )
1731
- first = _get_firstbday (wkday )
1732
- result = datetime (other .year , other .month , first ,
1733
- other .hour , other .minute , other .second ,
1734
- other .microsecond )
1735
- return result
1701
+ return shift_month (other , 3 * n - monthsSince , 'business_start' )
1736
1702
1737
1703
1738
1704
class QuarterEnd (EndMixin , QuarterOffset ):
@@ -1841,8 +1807,7 @@ class BYearEnd(YearOffset):
1841
1807
def apply (self , other ):
1842
1808
n = self .n
1843
1809
wkday , days_in_month = tslib .monthrange (other .year , self .month )
1844
- lastBDay = (days_in_month -
1845
- max (((wkday + days_in_month - 1 ) % 7 ) - 4 , 0 ))
1810
+ lastBDay = get_lastbday (wkday , days_in_month )
1846
1811
1847
1812
years = n
1848
1813
if n > 0 :
@@ -1854,17 +1819,8 @@ def apply(self, other):
1854
1819
(other .month == self .month and other .day > lastBDay )):
1855
1820
years += 1
1856
1821
1857
- other = shift_month (other , 12 * years , None )
1858
-
1859
- _ , days_in_month = tslib .monthrange (other .year , self .month )
1860
- result = datetime (other .year , self .month , days_in_month ,
1861
- other .hour , other .minute , other .second ,
1862
- other .microsecond )
1863
-
1864
- if result .weekday () > 4 :
1865
- result = result - BDay ()
1866
-
1867
- return result
1822
+ months = years * 12 + (self .month - other .month )
1823
+ return shift_month (other , months , 'business_end' )
1868
1824
1869
1825
1870
1826
class BYearBegin (YearOffset ):
@@ -1878,7 +1834,7 @@ def apply(self, other):
1878
1834
n = self .n
1879
1835
wkday , days_in_month = tslib .monthrange (other .year , self .month )
1880
1836
1881
- first = _get_firstbday (wkday )
1837
+ first = get_firstbday (wkday )
1882
1838
1883
1839
years = n
1884
1840
@@ -1892,11 +1848,8 @@ def apply(self, other):
1892
1848
years += 1
1893
1849
1894
1850
# set first bday for result
1895
- other = shift_month (other , years * 12 , None )
1896
- wkday , days_in_month = tslib .monthrange (other .year , self .month )
1897
- first = _get_firstbday (wkday )
1898
- return datetime (other .year , self .month , first , other .hour ,
1899
- other .minute , other .second , other .microsecond )
1851
+ months = years * 12 + (self .month - other .month )
1852
+ return shift_month (other , months , 'business_start' )
1900
1853
1901
1854
1902
1855
class YearEnd (EndMixin , YearOffset ):
0 commit comments