@@ -599,7 +599,7 @@ def _period_group(freqstr):
599599def _period_str_to_code (freqstr ):
600600 # hack
601601 freqstr = _rule_aliases .get (freqstr , freqstr )
602-
602+
603603 if freqstr not in _dont_uppercase :
604604 freqstr = _rule_aliases .get (freqstr .lower (), freqstr )
605605
@@ -659,6 +659,25 @@ def infer_freq(index, warn=True):
659659_ONE_HOUR = 60 * _ONE_MINUTE
660660_ONE_DAY = 24 * _ONE_HOUR
661661
662+ def _tz_convert_with_transitions (values , to_tz , from_tz ):
663+ """
664+ convert i8 values from the specificed timezone to the to_tz zone, taking
665+ into account DST transitions
666+ """
667+
668+ # vectorization is slow, so tests if we can do this via the faster tz_convert
669+ f = lambda x : tslib .tz_convert_single (x , to_tz , from_tz )
670+
671+ if len (values ) > 2 :
672+ first_slow , last_slow = f (values [0 ]),f (values [- 1 ])
673+
674+ first_fast , last_fast = tslib .tz_convert (np .array ([values [0 ],values [- 1 ]],dtype = 'i8' ),to_tz ,from_tz )
675+
676+ # don't cross a DST, so ok
677+ if first_fast == first_slow and last_fast == last_slow :
678+ return tslib .tz_convert (values ,to_tz ,from_tz )
679+
680+ return np .vectorize (f )(values )
662681
663682class _FrequencyInferer (object ):
664683 """
@@ -670,10 +689,7 @@ def __init__(self, index, warn=True):
670689 self .values = np .asarray (index ).view ('i8' )
671690
672691 if index .tz is not None :
673- f = lambda x : tslib .tz_convert_single (x , 'UTC' , index .tz )
674- self .values = np .vectorize (f )(self .values )
675- # This cant work, because of DST
676- # self.values = tslib.tz_convert(self.values, 'UTC', index.tz)
692+ self .values = _tz_convert_with_transitions (self .values ,'UTC' ,index .tz )
677693
678694 self .warn = warn
679695
0 commit comments