@@ -599,7 +599,7 @@ def _period_group(freqstr):
599
599
def _period_str_to_code (freqstr ):
600
600
# hack
601
601
freqstr = _rule_aliases .get (freqstr , freqstr )
602
-
602
+
603
603
if freqstr not in _dont_uppercase :
604
604
freqstr = _rule_aliases .get (freqstr .lower (), freqstr )
605
605
@@ -659,6 +659,25 @@ def infer_freq(index, warn=True):
659
659
_ONE_HOUR = 60 * _ONE_MINUTE
660
660
_ONE_DAY = 24 * _ONE_HOUR
661
661
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 )
662
681
663
682
class _FrequencyInferer (object ):
664
683
"""
@@ -670,10 +689,7 @@ def __init__(self, index, warn=True):
670
689
self .values = np .asarray (index ).view ('i8' )
671
690
672
691
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 )
677
693
678
694
self .warn = warn
679
695
0 commit comments