@@ -712,19 +712,23 @@ void pandas_timedelta_to_timedeltastruct(npy_timedelta td,
712
712
npy_int64 sfrac ;
713
713
npy_int64 ifrac ;
714
714
int sign ;
715
- npy_int64 DAY_NS = 86400000000000LL ;
715
+ npy_int64 per_day ;
716
+ npy_int64 per_sec ;
716
717
717
718
/* Initialize the output to all zeros */
718
719
memset (out , 0 , sizeof (pandas_timedeltastruct ));
719
720
720
721
switch (base ) {
721
722
case NPY_FR_ns :
722
723
724
+ per_day = 86400000000000LL ;
725
+ per_sec = 1000LL * 1000LL * 1000LL ;
726
+
723
727
// put frac in seconds
724
- if (td < 0 && td % ( 1000LL * 1000LL * 1000LL ) != 0 )
725
- frac = td / ( 1000LL * 1000LL * 1000LL ) - 1 ;
728
+ if (td < 0 && td % per_sec != 0 )
729
+ frac = td / per_sec - 1 ;
726
730
else
727
- frac = td / ( 1000LL * 1000LL * 1000LL ) ;
731
+ frac = td / per_sec ;
728
732
729
733
if (frac < 0 ) {
730
734
sign = -1 ;
@@ -768,12 +772,12 @@ void pandas_timedelta_to_timedeltastruct(npy_timedelta td,
768
772
}
769
773
770
774
sfrac = (out -> hrs * 3600LL + out -> min * 60LL
771
- + out -> sec ) * ( 1000LL * 1000LL * 1000LL ) ;
775
+ + out -> sec ) * per_sec ;
772
776
773
777
if (sign < 0 )
774
778
out -> days = - out -> days ;
775
779
776
- ifrac = td - (out -> days * DAY_NS + sfrac );
780
+ ifrac = td - (out -> days * per_day + sfrac );
777
781
778
782
if (ifrac != 0 ) {
779
783
out -> ms = ifrac / (1000LL * 1000LL );
@@ -786,17 +790,233 @@ void pandas_timedelta_to_timedeltastruct(npy_timedelta td,
786
790
out -> us = 0 ;
787
791
out -> ns = 0 ;
788
792
}
793
+ break ;
794
+
795
+ case NPY_FR_us :
796
+
797
+ per_day = 86400000000LL ;
798
+ per_sec = 1000LL * 1000LL ;
799
+
800
+ // put frac in seconds
801
+ if (td < 0 && td % per_sec != 0 )
802
+ frac = td / per_sec - 1 ;
803
+ else
804
+ frac = td / per_sec ;
805
+
806
+ if (frac < 0 ) {
807
+ sign = -1 ;
808
+
809
+ // even fraction
810
+ if ((- frac % 86400LL ) != 0 ) {
811
+ out -> days = - frac / 86400LL + 1 ;
812
+ frac += 86400LL * out -> days ;
813
+ } else {
814
+ frac = - frac ;
815
+ }
816
+ } else {
817
+ sign = 1 ;
818
+ out -> days = 0 ;
819
+ }
820
+
821
+ if (frac >= 86400 ) {
822
+ out -> days += frac / 86400LL ;
823
+ frac -= out -> days * 86400LL ;
824
+ }
825
+
826
+ if (frac >= 3600 ) {
827
+ out -> hrs = frac / 3600LL ;
828
+ frac -= out -> hrs * 3600LL ;
829
+ } else {
830
+ out -> hrs = 0 ;
831
+ }
832
+
833
+ if (frac >= 60 ) {
834
+ out -> min = frac / 60LL ;
835
+ frac -= out -> min * 60LL ;
836
+ } else {
837
+ out -> min = 0 ;
838
+ }
839
+
840
+ if (frac >= 0 ) {
841
+ out -> sec = frac ;
842
+ frac -= out -> sec ;
843
+ } else {
844
+ out -> sec = 0 ;
845
+ }
846
+
847
+ sfrac = (out -> hrs * 3600LL + out -> min * 60LL
848
+ + out -> sec ) * per_sec ;
849
+
850
+ if (sign < 0 )
851
+ out -> days = - out -> days ;
852
+
853
+ ifrac = td - (out -> days * per_day + sfrac );
854
+
855
+ if (ifrac != 0 ) {
856
+ out -> ms = ifrac / 1000LL ;
857
+ ifrac -= out -> ms * 1000LL ;
858
+ out -> us = ifrac / 1L ;
859
+ ifrac -= out -> us * 1L ;
860
+ out -> ns = ifrac ;
861
+ } else {
862
+ out -> ms = 0 ;
863
+ out -> us = 0 ;
864
+ out -> ns = 0 ;
865
+ }
866
+ break ;
867
+
868
+ case NPY_FR_ms :
869
+
870
+ per_day = 86400000LL ;
871
+ per_sec = 1000LL ;
872
+
873
+ // put frac in seconds
874
+ if (td < 0 && td % per_sec != 0 )
875
+ frac = td / per_sec - 1 ;
876
+ else
877
+ frac = td / per_sec ;
878
+
879
+ if (frac < 0 ) {
880
+ sign = -1 ;
881
+
882
+ // even fraction
883
+ if ((- frac % 86400LL ) != 0 ) {
884
+ out -> days = - frac / 86400LL + 1 ;
885
+ frac += 86400LL * out -> days ;
886
+ } else {
887
+ frac = - frac ;
888
+ }
889
+ } else {
890
+ sign = 1 ;
891
+ out -> days = 0 ;
892
+ }
893
+
894
+ if (frac >= 86400 ) {
895
+ out -> days += frac / 86400LL ;
896
+ frac -= out -> days * 86400LL ;
897
+ }
898
+
899
+ if (frac >= 3600 ) {
900
+ out -> hrs = frac / 3600LL ;
901
+ frac -= out -> hrs * 3600LL ;
902
+ } else {
903
+ out -> hrs = 0 ;
904
+ }
905
+
906
+ if (frac >= 60 ) {
907
+ out -> min = frac / 60LL ;
908
+ frac -= out -> min * 60LL ;
909
+ } else {
910
+ out -> min = 0 ;
911
+ }
912
+
913
+ if (frac >= 0 ) {
914
+ out -> sec = frac ;
915
+ frac -= out -> sec ;
916
+ } else {
917
+ out -> sec = 0 ;
918
+ }
919
+
920
+ sfrac = (out -> hrs * 3600LL + out -> min * 60LL
921
+ + out -> sec ) * per_sec ;
922
+
923
+ if (sign < 0 )
924
+ out -> days = - out -> days ;
925
+
926
+ ifrac = td - (out -> days * per_day + sfrac );
927
+
928
+ if (ifrac != 0 ) {
929
+ out -> ms = ifrac ;
930
+ out -> us = 0 ;
931
+ out -> ns = 0 ;
932
+ } else {
933
+ out -> ms = 0 ;
934
+ out -> us = 0 ;
935
+ out -> ns = 0 ;
936
+ }
937
+ break ;
938
+
939
+ case NPY_FR_s :
940
+ // special case where we can simplify many expressions bc per_sec=1
941
+
942
+ per_day = 86400000LL ;
943
+ per_sec = 1L ;
944
+
945
+ // put frac in seconds
946
+ if (td < 0 && td % per_sec != 0 )
947
+ frac = td / per_sec - 1 ;
948
+ else
949
+ frac = td / per_sec ;
950
+
951
+ if (frac < 0 ) {
952
+ sign = -1 ;
789
953
790
- out -> seconds = out -> hrs * 3600 + out -> min * 60 + out -> sec ;
791
- out -> microseconds = out -> ms * 1000 + out -> us ;
792
- out -> nanoseconds = out -> ns ;
954
+ // even fraction
955
+ if ((- frac % 86400LL ) != 0 ) {
956
+ out -> days = - frac / 86400LL + 1 ;
957
+ frac += 86400LL * out -> days ;
958
+ } else {
959
+ frac = - frac ;
960
+ }
961
+ } else {
962
+ sign = 1 ;
963
+ out -> days = 0 ;
964
+ }
965
+
966
+ if (frac >= 86400 ) {
967
+ out -> days += frac / 86400LL ;
968
+ frac -= out -> days * 86400LL ;
969
+ }
970
+
971
+ if (frac >= 3600 ) {
972
+ out -> hrs = frac / 3600LL ;
973
+ frac -= out -> hrs * 3600LL ;
974
+ } else {
975
+ out -> hrs = 0 ;
976
+ }
977
+
978
+ if (frac >= 60 ) {
979
+ out -> min = frac / 60LL ;
980
+ frac -= out -> min * 60LL ;
981
+ } else {
982
+ out -> min = 0 ;
983
+ }
984
+
985
+ if (frac >= 0 ) {
986
+ out -> sec = frac ;
987
+ frac -= out -> sec ;
988
+ } else {
989
+ out -> sec = 0 ;
990
+ }
991
+
992
+ sfrac = (out -> hrs * 3600LL + out -> min * 60LL
993
+ + out -> sec ) * per_sec ;
994
+
995
+ if (sign < 0 )
996
+ out -> days = - out -> days ;
997
+
998
+ ifrac = td - (out -> days * per_day + sfrac );
999
+
1000
+ if (ifrac != 0 ) {
1001
+ out -> ms = 0 ;
1002
+ out -> us = 0 ;
1003
+ out -> ns = 0 ;
1004
+ } else {
1005
+ out -> ms = 0 ;
1006
+ out -> us = 0 ;
1007
+ out -> ns = 0 ;
1008
+ }
793
1009
break ;
794
1010
795
1011
default :
796
1012
PyErr_SetString (PyExc_RuntimeError ,
797
1013
"NumPy timedelta metadata is corrupted with "
798
1014
"invalid base unit" );
799
1015
}
1016
+
1017
+ out -> seconds = out -> hrs * 3600 + out -> min * 60 + out -> sec ;
1018
+ out -> microseconds = out -> ms * 1000 + out -> us ;
1019
+ out -> nanoseconds = out -> ns ;
800
1020
}
801
1021
802
1022
0 commit comments