The commit information below represents what I submitted to upstream
in a pull request at debian/patches/replace-floating-point-with-integer.patch
the actual patch in this file differs slightly because of adaptations needed
to suit the version of the pacakge in Debian.

commit f5ed7667eb7639a480390d728153782119244bb1
Author: Peter Michael Green <plugwash@debian.org>
Date:   Sat Aug 21 20:53:05 2021 +0000

    Replace rounding-error prone floating point code with robust integer code.

Index: iso8601/src/parsers.rs
===================================================================
--- iso8601.orig/src/parsers.rs
+++ iso8601/src/parsers.rs
@@ -101,14 +101,6 @@ fn sign(i: &[u8]) -> IResult<&[u8], i32>
     })(i)
 }
 
-fn fractions(i: &[u8]) -> IResult<&[u8], f32> {
-    let (i, digits) = take_while(is_digit)(i)?;
-    let digits = str::from_utf8(digits).unwrap(); // This can't panic, `digits` will only include digits.
-    let f = format!("0.{}", digits).parse().unwrap(); // This can't panic, the string is a valid `f32`.
-
-    Ok((i, f))
-}
-
 // DATE
 
 // [+/-]YYYY
@@ -204,8 +196,25 @@ fn time_second(i: &[u8]) -> IResult<&[u8
     n_digit_in_range(i, 2, 0..=60)
 }
 
-fn time_millisecond(fraction: f32) -> u32 {
-    (1000.0 * fraction) as u32
+fn time_millisecond(i: &[u8]) -> IResult<&[u8], u32> {
+    let (i, mut digits) = take_while(is_digit)(i)?;
+    let mut l = digits.len();
+    if l > 3 {
+        digits = digits.get(0..3).unwrap();
+    }
+    let mut result = 0;
+    if l > 0 {
+        let digits = str::from_utf8(digits).unwrap(); // This can't panic, `digits` will only include digits.
+        result = digits.parse().unwrap();
+    }
+    while l < 3 {
+        result = result * 10;
+        l += 1;
+    }
+    //let fraction: f32 = format!("0.{}", digits).parse().unwrap(); // This can't panic, the string is a valid `f32`.
+
+    //let result = (1000.0 * fraction) as u32;
+    Ok ((i,result))
 }
 
 // HH:MM:[SS][.(m*)][(Z|+...|-...)]
@@ -216,7 +225,7 @@ pub fn parse_time(i: &[u8]) -> IResult<&
             opt(tag(b":")),                                                // :
             time_minute,                                                   // MM
             opt(preceded(opt(tag(b":")), time_second)),                    // [SS]
-            opt(map(preceded(one_of(",."), fractions), time_millisecond)), // [.(m*)]
+            opt(preceded(one_of(",."), time_millisecond)),                 // [.(m*)]
             opt(alt((timezone_hour, timezone_utc))),                       // [(Z|+...|-...)]
         )),
         |(h, _, m, s, ms, z)| {
@@ -288,13 +297,30 @@ fn duration_minute(i: &[u8]) -> IResult<
 // S[S][[,.][MS]]
 fn duration_second_and_millisecond(i: &[u8]) -> IResult<&[u8], (u32, u32)> {
     let (i, s) = m_to_n_digit_in_range(i, 1, 2, 0..=60)?;
-    let (i, ms) = opt(map(preceded(one_of(",."), fractions), duration_millisecond))(i)?;
+    let (i, ms) = opt(preceded(one_of(",."), duration_millisecond))(i)?;
 
     Ok((i, (s, ms.unwrap_or(0))))
 }
 
-fn duration_millisecond(fraction: f32) -> u32 {
-    (1000.0 * fraction) as u32
+fn duration_millisecond(i: &[u8]) -> IResult<&[u8], u32> {
+    let (i, mut digits) = take_while(is_digit)(i)?;
+    let mut l = digits.len();
+    if l > 3 {
+        digits = digits.get(0..3).unwrap();
+    }
+    let mut result = 0;
+    if l > 0 {
+        let digits = str::from_utf8(digits).unwrap(); // This can't panic, `digits` will only include digits.
+        result = digits.parse().unwrap();
+    }
+    while l < 3 {
+        result = result * 10;
+        l += 1;
+    }
+    //let fraction: f32 = format!("0.{}", digits).parse().unwrap(); // This can't panic, the string is a valid `f32`.
+
+    //let result = (1000.0 * fraction) as u32;
+    Ok ((i,result))
 }
 
 fn duration_time(i: &[u8]) -> IResult<&[u8], (u32, u32, u32, u32)> {
Index: iso8601/tests/lib.rs
===================================================================
--- iso8601.orig/tests/lib.rs
+++ iso8601/tests/lib.rs
@@ -22,6 +22,21 @@ fn test_date() {
 
 #[test]
 fn test_millisecond() {
+    let mut i=0;
+    while i < 1000 {
+      assert_eq!(
+        Ok(Time {
+            hour: 16,
+            minute: 43,
+            second: 0,
+            millisecond: i,
+            tz_offset_hours: 0,
+            tz_offset_minutes: 0
+        }),
+        time(format!("16:43:00.{:0>3}",i).as_str())
+      );
+      i+=1;
+    }
     assert_eq!(
         Ok(Time {
             hour: 16,
