@@ -682,19 +682,23 @@ void pandas_timedelta_to_timedeltastruct(npy_timedelta td,
682
682
npy_int64 sfrac ;
683
683
npy_int64 ifrac ;
684
684
int sign ;
685
- npy_int64 DAY_NS = 86400000000000LL ;
685
+ npy_int64 PER_DAY ;
686
+ npy_int64 PER_SEC ;
686
687
687
688
/* Initialize the output to all zeros */
688
689
memset (out , 0 , sizeof (pandas_timedeltastruct ));
689
690
690
691
switch (base ) {
691
692
case NPY_FR_ns :
692
693
694
+ PER_DAY = 86400000000000LL ;
695
+ PER_SEC = 1000LL * 1000LL * 1000LL ;
696
+
693
697
// put frac in seconds
694
- if (td < 0 && td % ( 1000LL * 1000LL * 1000LL ) != 0 )
695
- frac = td / ( 1000LL * 1000LL * 1000LL ) - 1 ;
698
+ if (td < 0 && td % PER_SEC != 0 )
699
+ frac = td / PER_SEC - 1 ;
696
700
else
697
- frac = td / ( 1000LL * 1000LL * 1000LL ) ;
701
+ frac = td / PER_SEC ;
698
702
699
703
if (frac < 0 ) {
700
704
sign = -1 ;
@@ -738,12 +742,12 @@ void pandas_timedelta_to_timedeltastruct(npy_timedelta td,
738
742
}
739
743
740
744
sfrac = (out -> hrs * 3600LL + out -> min * 60LL
741
- + out -> sec ) * ( 1000LL * 1000LL * 1000LL ) ;
745
+ + out -> sec ) * PER_SEC ;
742
746
743
747
if (sign < 0 )
744
748
out -> days = - out -> days ;
745
749
746
- ifrac = td - (out -> days * DAY_NS + sfrac );
750
+ ifrac = td - (out -> days * PER_DAY + sfrac );
747
751
748
752
if (ifrac != 0 ) {
749
753
out -> ms = ifrac / (1000LL * 1000LL );
@@ -762,11 +766,231 @@ void pandas_timedelta_to_timedeltastruct(npy_timedelta td,
762
766
out -> nanoseconds = out -> ns ;
763
767
break ;
764
768
769
+ case NPY_FR_us :
770
+
771
+ PER_DAY = 86400000000LL ;
772
+ PER_SEC = 1000LL * 1000LL ;
773
+
774
+ // put frac in seconds
775
+ if (td < 0 && td % PER_SEC != 0 )
776
+ frac = td / PER_SEC - 1 ;
777
+ else
778
+ frac = td / PER_SEC ;
779
+
780
+ if (frac < 0 ) {
781
+ sign = -1 ;
782
+
783
+ // even fraction
784
+ if ((- frac % 86400LL ) != 0 ) {
785
+ out -> days = - frac / 86400LL + 1 ;
786
+ frac += 86400LL * out -> days ;
787
+ } else {
788
+ frac = - frac ;
789
+ }
790
+ } else {
791
+ sign = 1 ;
792
+ out -> days = 0 ;
793
+ }
794
+
795
+ if (frac >= 86400 ) {
796
+ out -> days += frac / 86400LL ;
797
+ frac -= out -> days * 86400LL ;
798
+ }
799
+
800
+ if (frac >= 3600 ) {
801
+ out -> hrs = frac / 3600LL ;
802
+ frac -= out -> hrs * 3600LL ;
803
+ } else {
804
+ out -> hrs = 0 ;
805
+ }
806
+
807
+ if (frac >= 60 ) {
808
+ out -> min = frac / 60LL ;
809
+ frac -= out -> min * 60LL ;
810
+ } else {
811
+ out -> min = 0 ;
812
+ }
813
+
814
+ if (frac >= 0 ) {
815
+ out -> sec = frac ;
816
+ frac -= out -> sec ;
817
+ } else {
818
+ out -> sec = 0 ;
819
+ }
820
+
821
+ sfrac = (out -> hrs * 3600LL + out -> min * 60LL
822
+ + out -> sec ) * PER_SEC ;
823
+
824
+ if (sign < 0 )
825
+ out -> days = - out -> days ;
826
+
827
+ ifrac = td - (out -> days * PER_DAY + sfrac );
828
+
829
+ if (ifrac != 0 ) {
830
+ out -> ms = ifrac / 1000LL ;
831
+ ifrac -= out -> ms * 1000LL ;
832
+ out -> us = ifrac / 1L ;
833
+ ifrac -= out -> us * 1L ;
834
+ out -> ns = ifrac ;
835
+ } else {
836
+ out -> ms = 0 ;
837
+ out -> us = 0 ;
838
+ out -> ns = 0 ;
839
+ }
840
+ break ;
841
+
842
+ case NPY_FR_ms :
843
+
844
+ PER_DAY = 86400000LL ;
845
+ PER_SEC = 1000LL ;
846
+
847
+ // put frac in seconds
848
+ if (td < 0 && td % PER_SEC != 0 )
849
+ frac = td / PER_SEC - 1 ;
850
+ else
851
+ frac = td / PER_SEC ;
852
+
853
+ if (frac < 0 ) {
854
+ sign = -1 ;
855
+
856
+ // even fraction
857
+ if ((- frac % 86400LL ) != 0 ) {
858
+ out -> days = - frac / 86400LL + 1 ;
859
+ frac += 86400LL * out -> days ;
860
+ } else {
861
+ frac = - frac ;
862
+ }
863
+ } else {
864
+ sign = 1 ;
865
+ out -> days = 0 ;
866
+ }
867
+
868
+ if (frac >= 86400 ) {
869
+ out -> days += frac / 86400LL ;
870
+ frac -= out -> days * 86400LL ;
871
+ }
872
+
873
+ if (frac >= 3600 ) {
874
+ out -> hrs = frac / 3600LL ;
875
+ frac -= out -> hrs * 3600LL ;
876
+ } else {
877
+ out -> hrs = 0 ;
878
+ }
879
+
880
+ if (frac >= 60 ) {
881
+ out -> min = frac / 60LL ;
882
+ frac -= out -> min * 60LL ;
883
+ } else {
884
+ out -> min = 0 ;
885
+ }
886
+
887
+ if (frac >= 0 ) {
888
+ out -> sec = frac ;
889
+ frac -= out -> sec ;
890
+ } else {
891
+ out -> sec = 0 ;
892
+ }
893
+
894
+ sfrac = (out -> hrs * 3600LL + out -> min * 60LL
895
+ + out -> sec ) * PER_SEC ;
896
+
897
+ if (sign < 0 )
898
+ out -> days = - out -> days ;
899
+
900
+ ifrac = td - (out -> days * PER_DAY + sfrac );
901
+
902
+ if (ifrac != 0 ) {
903
+ out -> ms = ifrac ;
904
+ out -> us = 0 ;
905
+ out -> ns = 0 ;
906
+ } else {
907
+ out -> ms = 0 ;
908
+ out -> us = 0 ;
909
+ out -> ns = 0 ;
910
+ }
911
+ break ;
912
+
913
+ case NPY_FR_s :
914
+ // special case where we can simplify many expressions bc PER_SEC=1
915
+
916
+ PER_DAY = 86400000LL ;
917
+ PER_SEC = 1L ;
918
+
919
+ // put frac in seconds
920
+ if (td < 0 && td % PER_SEC != 0 )
921
+ frac = td / PER_SEC - 1 ;
922
+ else
923
+ frac = td / PER_SEC ;
924
+
925
+ if (frac < 0 ) {
926
+ sign = -1 ;
927
+
928
+ // even fraction
929
+ if ((- frac % 86400LL ) != 0 ) {
930
+ out -> days = - frac / 86400LL + 1 ;
931
+ frac += 86400LL * out -> days ;
932
+ } else {
933
+ frac = - frac ;
934
+ }
935
+ } else {
936
+ sign = 1 ;
937
+ out -> days = 0 ;
938
+ }
939
+
940
+ if (frac >= 86400 ) {
941
+ out -> days += frac / 86400LL ;
942
+ frac -= out -> days * 86400LL ;
943
+ }
944
+
945
+ if (frac >= 3600 ) {
946
+ out -> hrs = frac / 3600LL ;
947
+ frac -= out -> hrs * 3600LL ;
948
+ } else {
949
+ out -> hrs = 0 ;
950
+ }
951
+
952
+ if (frac >= 60 ) {
953
+ out -> min = frac / 60LL ;
954
+ frac -= out -> min * 60LL ;
955
+ } else {
956
+ out -> min = 0 ;
957
+ }
958
+
959
+ if (frac >= 0 ) {
960
+ out -> sec = frac ;
961
+ frac -= out -> sec ;
962
+ } else {
963
+ out -> sec = 0 ;
964
+ }
965
+
966
+ sfrac = (out -> hrs * 3600LL + out -> min * 60LL
967
+ + out -> sec ) * PER_SEC ;
968
+
969
+ if (sign < 0 )
970
+ out -> days = - out -> days ;
971
+
972
+ ifrac = td - (out -> days * PER_DAY + sfrac );
973
+
974
+ if (ifrac != 0 ) {
975
+ out -> ms = 0 ;
976
+ out -> us = 0 ;
977
+ out -> ns = 0 ;
978
+ } else {
979
+ out -> ms = 0 ;
980
+ out -> us = 0 ;
981
+ out -> ns = 0 ;
982
+ }
983
+ break ;
984
+
765
985
default :
766
986
PyErr_SetString (PyExc_RuntimeError ,
767
987
"NumPy timedelta metadata is corrupted with "
768
988
"invalid base unit" );
769
989
}
990
+
991
+ out -> seconds = out -> hrs * 3600 + out -> min * 60 + out -> sec ;
992
+ out -> microseconds = out -> ms * 1000 + out -> us ;
993
+ out -> nanoseconds = out -> ns ;
770
994
}
771
995
772
996
0 commit comments