1313from datetime import datetime , timedelta
1414from distutils .version import LooseVersion
1515from pytz .exceptions import AmbiguousTimeError , NonExistentTimeError
16+ from collections import namedtuple
1617
1718import pandas .util .testing as tm
1819import pandas .util ._test_decorators as td
@@ -656,82 +657,102 @@ def test_to_pydatetime_nonzero_nano(self):
656657 result = ts .to_pydatetime ()
657658 assert result == expected
658659
659- def test_round (self ):
660-
661- # round
662- dt = Timestamp ('20130101 09:10:11' )
663- result = dt .round ('D' )
664- expected = Timestamp ('20130101' )
665- assert result == expected
666-
667- dt = Timestamp ('20130101 19:10:11' )
668- result = dt .round ('D' )
669- expected = Timestamp ('20130102' )
670- assert result == expected
671-
672- dt = Timestamp ('20130201 12:00:00' )
673- result = dt .round ('D' )
674- expected = Timestamp ('20130202' )
675- assert result == expected
660+ TStestcase = namedtuple ('Tstestcase' ,
661+ ['input' , 'rounder' , 'freq' , 'expected' , 'kw' ])
662+
663+ def _check_round (self , cases ):
664+ for case in cases :
665+ dt = Timestamp (case .input , ** case .kw )
666+ rounder = getattr (dt , case .rounder )
667+ freqs = ([case .freq ] if not isinstance (case .freq , list )
668+ else case .freq )
669+ expected = ([case .expected ] if not isinstance (case .expected , list )
670+ else case .expected )
671+ if len (expected ) != len (freqs ):
672+ pairs = zip (freqs , expected * len (freqs ))
673+ else :
674+ pairs = zip (freqs , expected )
675+
676+ for freq , expect in pairs :
677+ result = rounder (freq )
678+ expected = Timestamp (expect , ** case .kw )
679+ assert result == expected , ('input={input}, '
680+ 'rounder={rounder}, '
681+ 'freq={freq}, expected={expect}, '
682+ 'kw={kw}'
683+ .format (input = case .input ,
684+ rounder = case .rounder ,
685+ freq = freq ,
686+ expect = expect ,
687+ kw = case .kw ))
688+
689+ def test_floor_timestamp (self ):
690+ cases = [
691+ # floor
692+ self .TStestcase ('20130101 09:10:11' , 'floor' , 'D' , '20130101' , {}),
693+ # GH19206
694+ self .TStestcase ('2117-01-01 00:00:45' , 'floor' , '15s' ,
695+ '2117-01-01 00:00:45' , {}),
696+ # GH19206
697+ self .TStestcase ('2117-01-01 00:00:45.000000012' , 'floor' , '10ns' ,
698+ '2117-01-01 00:00:45.000000010' , {}),
699+ # GH19206
700+ self .TStestcase ('1823-01-01 00:00:01' , 'floor' , '1s' ,
701+ '1823-01-01 00:00:01' , {}),
702+ # GH19206
703+ self .TStestcase ('1823-01-01 00:00:01.000000012' , 'floor' , '10ns' ,
704+ '1823-01-01 00:00:01.000000010' , {})
705+ ]
706+ self ._check_round (cases )
707+
708+ def test_ceil_timestamp (self ):
709+ cases = [
710+ # ceil
711+ self .TStestcase ('20130101 09:10:11' , 'ceil' , 'D' , '20130102' , {})
712+ ]
713+ self ._check_round (cases )
714+
715+ def test_round_timestamp (self ):
716+
717+ cases = [
718+ self .TStestcase ('20130101 09:10:11' , 'round' , 'D' , '20130101' , {}),
719+ self .TStestcase ('20130101 19:10:11' , 'round' , 'D' , '20130102' , {}),
720+ self .TStestcase ('20130201 12:00:00' , 'round' , 'D' , '20130202' , {}),
721+ self .TStestcase ('20130104 12:00:00' , 'round' , 'D' , '20130105' , {}),
722+ self .TStestcase ('20130104 12:32:00' , 'round' , '30Min' ,
723+ '20130104 12:30:00' , {}),
724+ # round with tz
725+ self .TStestcase ('20130101 09:10:11' , 'round' , 'D' , '20130101' ,
726+ {'tz' : 'US/Eastern' }),
727+ self .TStestcase ('20130101 09:10:11' , 'round' , 's' ,
728+ '20130101 09:10:11' , {'tz' : 'US/Eastern' }),
729+ # GH 14440 & 15578
730+ self .TStestcase ('2016-10-17 12:00:00.0015' , 'round' , 'ms' ,
731+ '2016-10-17 12:00:00.002000' , {}),
732+ self .TStestcase ('2016-10-17 12:00:00.00149' , 'round' , 'ms' ,
733+ '2016-10-17 12:00:00.001000' , {}),
734+ self .TStestcase ('2016-10-17 12:00:00.0015' , 'round' , ['us' , 'ns' ],
735+ '2016-10-17 12:00:00.0015' , {}),
736+ self .TStestcase ('2016-10-17 12:00:00.001501031' , 'round' , '10ns' ,
737+ '2016-10-17 12:00:00.001501030' , {}),
738+ self .TStestcase ('2000-01-05 05:09:15.13' , 'round' , ['D' , 'H' , 'S' ],
739+ ['2000-01-05 00:00:00' , '2000-01-05 05:00:00' ,
740+ '2000-01-05 05:09:15' ], {})
741+ ]
742+ self ._check_round (cases )
676743
677- dt = Timestamp ('20130104 12:00:00' )
678- result = dt .round ('D' )
679- expected = Timestamp ('20130105' )
680- assert result == expected
744+ with tm .assert_raises_regex (ValueError , _INVALID_FREQ_ERROR ):
745+ Timestamp ('2000-01-05 05:09:15.13' ).round ('foo' )
681746
682- dt = Timestamp ('20130104 12:32:00' )
683- result = dt .round ('30Min' )
684- expected = Timestamp ('20130104 12:30:00' )
685- assert result == expected
747+ with tm .assert_produces_warning ():
748+ Timestamp ('2016-10-17 12:00:00.001501031' ).round ('1010ns' )
686749
750+ def test_round_daterange (self ):
687751 dti = date_range ('20130101 09:10:11' , periods = 5 )
688752 result = dti .round ('D' )
689753 expected = date_range ('20130101' , periods = 5 )
690754 tm .assert_index_equal (result , expected )
691755
692- # floor
693- dt = Timestamp ('20130101 09:10:11' )
694- result = dt .floor ('D' )
695- expected = Timestamp ('20130101' )
696- assert result == expected
697-
698- # GH 19206
699- dt = Timestamp ('2117-01-01 00:00:45' )
700- result = dt .floor ('15s' )
701- expected = Timestamp ('2117-01-01 00:00:45' )
702- assert result == expected
703-
704- dt = Timestamp ('2117-01-01 00:00:45.000000012' )
705- result = dt .floor ('10ns' )
706- expected = Timestamp ('2117-01-01 00:00:45.000000010' )
707- assert result == expected
708-
709- dt = Timestamp ('1823-01-01 00:00:01' )
710- result = dt .floor ('1s' )
711- expected = Timestamp ('1823-01-01 00:00:01' )
712- assert result == expected
713-
714- dt = Timestamp ('1823-01-01 00:00:01.000000012' )
715- result = dt .floor ('10ns' )
716- expected = Timestamp ('1823-01-01 00:00:01.000000010' )
717- assert result == expected
718-
719- # ceil
720- dt = Timestamp ('20130101 09:10:11' )
721- result = dt .ceil ('D' )
722- expected = Timestamp ('20130102' )
723- assert result == expected
724-
725- # round with tz
726- dt = Timestamp ('20130101 09:10:11' , tz = 'US/Eastern' )
727- result = dt .round ('D' )
728- expected = Timestamp ('20130101' , tz = 'US/Eastern' )
729- assert result == expected
730-
731- dt = Timestamp ('20130101 09:10:11' , tz = 'US/Eastern' )
732- result = dt .round ('s' )
733- assert result == dt
734-
735756 dti = date_range ('20130101 09:10:11' ,
736757 periods = 5 ).tz_localize ('UTC' ).tz_convert ('US/Eastern' )
737758 result = dti .round ('D' )
@@ -745,41 +766,6 @@ def test_round(self):
745766 for freq in ['Y' , 'M' , 'foobar' ]:
746767 pytest .raises (ValueError , lambda : dti .round (freq ))
747768
748- # GH 14440 & 15578
749- result = Timestamp ('2016-10-17 12:00:00.0015' ).round ('ms' )
750- expected = Timestamp ('2016-10-17 12:00:00.002000' )
751- assert result == expected
752-
753- result = Timestamp ('2016-10-17 12:00:00.00149' ).round ('ms' )
754- expected = Timestamp ('2016-10-17 12:00:00.001000' )
755- assert result == expected
756-
757- ts = Timestamp ('2016-10-17 12:00:00.0015' )
758- for freq in ['us' , 'ns' ]:
759- assert ts == ts .round (freq )
760-
761- result = Timestamp ('2016-10-17 12:00:00.001501031' ).round ('10ns' )
762- expected = Timestamp ('2016-10-17 12:00:00.001501030' )
763- assert result == expected
764-
765- with tm .assert_produces_warning ():
766- Timestamp ('2016-10-17 12:00:00.001501031' ).round ('1010ns' )
767-
768- def test_round_misc (self ):
769- stamp = Timestamp ('2000-01-05 05:09:15.13' )
770-
771- def _check_round (freq , expected ):
772- result = stamp .round (freq = freq )
773- assert result == expected
774-
775- for freq , expected in [('D' , Timestamp ('2000-01-05 00:00:00' )),
776- ('H' , Timestamp ('2000-01-05 05:00:00' )),
777- ('S' , Timestamp ('2000-01-05 05:09:15' ))]:
778- _check_round (freq , expected )
779-
780- with tm .assert_raises_regex (ValueError , _INVALID_FREQ_ERROR ):
781- stamp .round ('foo' )
782-
783769 def test_class_ops_pytz (self ):
784770 def compare (x , y ):
785771 assert (int (Timestamp (x ).value / 1e9 ) ==
0 commit comments