@@ -48,13 +48,20 @@ def wrapper(self, other):
4848 elif isinstance (other , np .datetime64 ):
4949 other = as_timestamp (other )
5050
51+ tz = getattr (other , 'tzinfo' , None )
5152 result = func (self , other )
5253
5354 if self .normalize :
5455 result = tslib .normalize_date (result )
5556
5657 if isinstance (other , Timestamp ) and not isinstance (result , Timestamp ):
5758 result = as_timestamp (result )
59+
60+ if tz is not None :
61+ if isinstance (result , Timestamp ) and result .tzinfo is None :
62+ result = result .tz_localize (tz )
63+ elif isinstance (result , datetime ) and result .tzinfo is None :
64+ result = tz .localize (result )
5865 return result
5966 return wrapper
6067
@@ -570,6 +577,11 @@ def _to_dt64(dt, dtype='datetime64'):
570577 # > np.datetime64(dt.datetime(2013,5,1),dtype='datetime64[D]')
571578 # numpy.datetime64('2013-05-01T02:00:00.000000+0200')
572579 # Thus astype is needed to cast datetime to datetime64[D]
580+
581+ if getattr (dt , 'tzinfo' , None ) is not None :
582+ i8 = tslib .pydt_to_i8 (dt )
583+ dt = tslib .tz_convert_single (i8 , 'UTC' , dt .tzinfo )
584+ dt = Timestamp (dt )
573585 dt = np .datetime64 (dt )
574586 if dt .dtype .name != dtype :
575587 dt = dt .astype (dtype )
@@ -966,13 +978,18 @@ def apply(self, other):
966978 months = self .n + 1
967979
968980 other = self .getOffsetOfMonth (as_datetime (other ) + relativedelta (months = months , day = 1 ))
969- other = datetime (other .year , other .month , other .day ,
970- base .hour , base .minute , base .second , base .microsecond )
981+ other = datetime (other .year , other .month , other .day , base .hour ,
982+ base .minute , base .second , base .microsecond )
983+ if getattr (other , 'tzinfo' , None ) is not None :
984+ other = other .tzinfo .localize (other )
971985 return other
972986
973987 def getOffsetOfMonth (self , dt ):
974988 w = Week (weekday = self .weekday )
989+
975990 d = datetime (dt .year , dt .month , 1 )
991+ if getattr (dt , 'tzinfo' , None ) is not None :
992+ d = dt .tzinfo .localize (d )
976993
977994 d = w .rollforward (d )
978995
@@ -985,6 +1002,8 @@ def onOffset(self, dt):
9851002 if self .normalize and not _is_normalized (dt ):
9861003 return False
9871004 d = datetime (dt .year , dt .month , dt .day )
1005+ if getattr (dt , 'tzinfo' , None ) is not None :
1006+ d = dt .tzinfo .localize (d )
9881007 return d == self .getOffsetOfMonth (dt )
9891008
9901009 @property
@@ -1056,6 +1075,8 @@ def apply(self, other):
10561075 def getOffsetOfMonth (self , dt ):
10571076 m = MonthEnd ()
10581077 d = datetime (dt .year , dt .month , 1 , dt .hour , dt .minute , dt .second , dt .microsecond )
1078+ if getattr (dt , 'tzinfo' , None ) is not None :
1079+ d = dt .tzinfo .localize (d )
10591080
10601081 eom = m .rollforward (d )
10611082
@@ -1134,6 +1155,10 @@ class BQuarterEnd(QuarterOffset):
11341155 @apply_wraps
11351156 def apply (self , other ):
11361157 n = self .n
1158+ base = other
1159+ other = datetime (other .year , other .month , other .day ,
1160+ other .hour , other .minute , other .second ,
1161+ other .microsecond )
11371162
11381163 wkday , days_in_month = tslib .monthrange (other .year , other .month )
11391164 lastBDay = days_in_month - max (((wkday + days_in_month - 1 )
@@ -1149,7 +1174,8 @@ def apply(self, other):
11491174 n = n + 1
11501175
11511176 other = as_datetime (other ) + relativedelta (months = monthsToGo + 3 * n , day = 31 )
1152-
1177+ if getattr (base , 'tzinfo' , None ) is not None :
1178+ other = base .tzinfo .localize (other )
11531179 if other .weekday () > 4 :
11541180 other = other - BDay ()
11551181
@@ -1216,6 +1242,8 @@ def apply(self, other):
12161242 result = datetime (other .year , other .month , first ,
12171243 other .hour , other .minute , other .second ,
12181244 other .microsecond )
1245+ if getattr (other , 'tzinfo' , None ) is not None :
1246+ result = other .tzinfo .localize (result )
12191247 return as_timestamp (result )
12201248
12211249
@@ -1242,6 +1270,10 @@ def isAnchored(self):
12421270 @apply_wraps
12431271 def apply (self , other ):
12441272 n = self .n
1273+ base = other
1274+ other = datetime (other .year , other .month , other .day ,
1275+ other .hour , other .minute , other .second ,
1276+ other .microsecond )
12451277 other = as_datetime (other )
12461278
12471279 wkday , days_in_month = tslib .monthrange (other .year , other .month )
@@ -1254,7 +1286,8 @@ def apply(self, other):
12541286 n = n - 1
12551287
12561288 other = other + relativedelta (months = monthsToGo + 3 * n , day = 31 )
1257-
1289+ if getattr (base , 'tzinfo' , None ) is not None :
1290+ other = base .tzinfo .localize (other )
12581291 return as_timestamp (other )
12591292
12601293 def onOffset (self , dt ):
@@ -1589,6 +1622,10 @@ def apply(self, other):
15891622 datetime (other .year , self .startingMonth , 1 ))
15901623 next_year = self .get_year_end (
15911624 datetime (other .year + 1 , self .startingMonth , 1 ))
1625+ if getattr (other , 'tzinfo' , None ) is not None :
1626+ prev_year = other .tzinfo .localize (prev_year )
1627+ cur_year = other .tzinfo .localize (cur_year )
1628+ next_year = other .tzinfo .localize (next_year )
15921629
15931630 if n > 0 :
15941631 if other == prev_year :
@@ -1647,7 +1684,9 @@ def get_year_end(self, dt):
16471684 return self ._get_year_end_last (dt )
16481685
16491686 def get_target_month_end (self , dt ):
1650- target_month = datetime (year = dt .year , month = self .startingMonth , day = 1 )
1687+ target_month = datetime (dt .year , self .startingMonth , 1 )
1688+ if getattr (dt , 'tzinfo' , None ) is not None :
1689+ target_month = dt .tzinfo .localize (target_month )
16511690 next_month_first_of = target_month + relativedelta (months = + 1 )
16521691 return next_month_first_of + relativedelta (days = - 1 )
16531692
@@ -1665,7 +1704,9 @@ def _get_year_end_nearest(self, dt):
16651704 return backward
16661705
16671706 def _get_year_end_last (self , dt ):
1668- current_year = datetime (year = dt .year , month = self .startingMonth , day = 1 )
1707+ current_year = datetime (dt .year , self .startingMonth , 1 )
1708+ if getattr (dt , 'tzinfo' , None ) is not None :
1709+ current_year = dt .tzinfo .localize (current_year )
16691710 return current_year + self ._offset_lwom
16701711
16711712 @property
@@ -1878,13 +1919,14 @@ class Easter(DateOffset):
18781919 '''
18791920 def __init__ (self , n = 1 , ** kwds ):
18801921 super (Easter , self ).__init__ (n , ** kwds )
1881-
1922+
18821923 @apply_wraps
18831924 def apply (self , other ):
1884-
18851925 currentEaster = easter (other .year )
18861926 currentEaster = datetime (currentEaster .year , currentEaster .month , currentEaster .day )
1887-
1927+ if getattr (other , 'tzinfo' , None ) is not None :
1928+ currentEaster = other .tzinfo .localize (currentEaster )
1929+
18881930 # NOTE: easter returns a datetime.date so we have to convert to type of other
18891931 if self .n >= 0 :
18901932 if other >= currentEaster :
@@ -1905,6 +1947,7 @@ def onOffset(self, dt):
19051947 if self .normalize and not _is_normalized (dt ):
19061948 return False
19071949 return date (dt .year , dt .month , dt .day ) == easter (dt .year )
1950+
19081951#----------------------------------------------------------------------
19091952# Ticks
19101953
0 commit comments