@@ -113,21 +113,38 @@ impl<'a> EitherTimedelta<'a> {
113
113
pub fn total_seconds ( & self ) -> PyResult < f64 > {
114
114
match self {
115
115
Self :: Raw ( timedelta) => {
116
- let days: f64 = f64:: from ( timedelta. day ) ;
117
- let seconds: f64 = f64:: from ( timedelta. second ) ;
118
- let microseconds: f64 = f64:: from ( timedelta. microsecond ) ;
119
- let total_seconds: f64 = if !timedelta. positive {
120
- -1.0 * ( 86400.0 * days + seconds + microseconds / 1_000_000.0 )
116
+ let mut days: i64 = i64:: from ( timedelta. day ) ;
117
+ let mut seconds: i64 = i64:: from ( timedelta. second ) ;
118
+ let mut microseconds = i64:: from ( timedelta. microsecond ) ;
119
+ if !timedelta. positive {
120
+ days = -days;
121
+ seconds = -seconds;
122
+ microseconds = -microseconds;
123
+ }
124
+
125
+ let days_seconds = ( 86_400 * days) + seconds;
126
+ if let Some ( days_seconds_as_micros) = days_seconds. checked_mul ( 1_000_000 ) {
127
+ let total_microseconds = days_seconds_as_micros + microseconds;
128
+ Ok ( total_microseconds as f64 / 1_000_000.0 )
121
129
} else {
122
- 86400.0 * days + seconds + microseconds / 1_000_000.0
123
- } ;
124
- Ok ( total_seconds)
130
+ // Fall back to floating-point operations if the multiplication overflows
131
+ let total_seconds = days_seconds as f64 + microseconds as f64 / 1_000_000.0 ;
132
+ Ok ( total_seconds)
133
+ }
125
134
}
126
135
Self :: PyExact ( py_timedelta) => {
127
- let days: f64 = f64:: from ( py_timedelta. get_days ( ) ) ; // -999999999 to 999999999
128
- let seconds: f64 = f64:: from ( py_timedelta. get_seconds ( ) ) ; // 0 through 86399
129
- let microseconds: f64 = f64:: from ( py_timedelta. get_microseconds ( ) ) ; // 0 through 999999
130
- Ok ( 86400.0 * days + seconds + microseconds / 1_000_000.0 )
136
+ let days: i64 = py_timedelta. get_days ( ) . into ( ) ; // -999999999 to 999999999
137
+ let seconds: i64 = py_timedelta. get_seconds ( ) . into ( ) ; // 0 through 86399
138
+ let microseconds = py_timedelta. get_microseconds ( ) ; // 0 through 999999
139
+ let days_seconds = ( 86_400 * days) + seconds;
140
+ if let Some ( days_seconds_as_micros) = days_seconds. checked_mul ( 1_000_000 ) {
141
+ let total_microseconds = days_seconds_as_micros + i64:: from ( microseconds) ;
142
+ Ok ( total_microseconds as f64 / 1_000_000.0 )
143
+ } else {
144
+ // Fall back to floating-point operations if the multiplication overflows
145
+ let total_seconds = days_seconds as f64 + f64:: from ( microseconds) / 1_000_000.0 ;
146
+ Ok ( total_seconds)
147
+ }
131
148
}
132
149
Self :: PySubclass ( py_timedelta) => py_timedelta
133
150
. call_method0 ( intern ! ( py_timedelta. py( ) , "total_seconds" ) ) ?
@@ -138,28 +155,45 @@ impl<'a> EitherTimedelta<'a> {
138
155
pub fn total_milliseconds ( & self ) -> PyResult < f64 > {
139
156
match self {
140
157
Self :: Raw ( timedelta) => {
141
- let days: f64 = f64:: from ( timedelta. day ) ;
142
- let seconds: f64 = f64:: from ( timedelta. second ) ;
143
- let microseconds: f64 = f64:: from ( timedelta. microsecond ) ;
144
- let total_seconds: f64 = if !timedelta. positive {
145
- -1.0 * ( 86_400_000.0 * days + seconds * 1_000.0 + microseconds / 1_000.0 )
158
+ let mut days: i64 = i64:: from ( timedelta. day ) ;
159
+ let mut seconds: i64 = i64:: from ( timedelta. second ) ;
160
+ let mut microseconds = i64:: from ( timedelta. microsecond ) ;
161
+ if !timedelta. positive {
162
+ days = -days;
163
+ seconds = -seconds;
164
+ microseconds = -microseconds;
165
+ }
166
+
167
+ let days_seconds = ( 86_400 * days) + seconds;
168
+ if let Some ( days_seconds_as_micros) = days_seconds. checked_mul ( 1_000_000 ) {
169
+ let total_microseconds = days_seconds_as_micros + microseconds;
170
+ Ok ( total_microseconds as f64 / 1_000.0 )
146
171
} else {
147
- 86_400_000.0 * days + seconds * 1_000.0 + microseconds / 1_000.0
148
- } ;
149
- Ok ( total_seconds)
172
+ // Fall back to floating-point operations if the multiplication overflows
173
+ let total_seconds = days_seconds as f64 + microseconds as f64 / 1_000.0 ;
174
+ Ok ( total_seconds)
175
+ }
150
176
}
151
177
Self :: PyExact ( py_timedelta) => {
152
- let days: f64 = f64:: from ( py_timedelta. get_days ( ) ) ; // -999999999 to 999999999
153
- let seconds: f64 = f64:: from ( py_timedelta. get_seconds ( ) ) ; // 0 through 86399
154
- let microseconds: f64 = f64:: from ( py_timedelta. get_microseconds ( ) ) ; // 0 through 999999
155
- Ok ( 86_400_000.0 * days + seconds * 1_000.0 + microseconds / 1_000.0 )
178
+ let days: i64 = py_timedelta. get_days ( ) . into ( ) ; // -999999999 to 999999999
179
+ let seconds: i64 = py_timedelta. get_seconds ( ) . into ( ) ; // 0 through 86399
180
+ let microseconds = py_timedelta. get_microseconds ( ) ; // 0 through 999999
181
+ let days_seconds = ( 86_400 * days) + seconds;
182
+ if let Some ( days_seconds_as_micros) = days_seconds. checked_mul ( 1_000_000 ) {
183
+ let total_microseconds = days_seconds_as_micros + i64:: from ( microseconds) ;
184
+ Ok ( total_microseconds as f64 / 1_000.0 )
185
+ } else {
186
+ // Fall back to floating-point operations if the multiplication overflows
187
+ let total_milliseconds = days_seconds as f64 * 1_000.0 + f64:: from ( microseconds) / 1_000.0 ;
188
+ Ok ( total_milliseconds)
189
+ }
156
190
}
157
191
Self :: PySubclass ( py_timedelta) => {
158
- let total_seconds = py_timedelta
192
+ let total_seconds: f64 = py_timedelta
159
193
. call_method0 ( intern ! ( py_timedelta. py( ) , "total_seconds" ) ) ?
160
194
. extract ( ) ?;
161
195
Ok ( total_seconds / 1000.0 )
162
- } ,
196
+ }
163
197
}
164
198
}
165
199
}
0 commit comments