diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index 0e4d23c9bb77a8fe98900f99ead1f1433e075cd2..c7d2c9862fcf7917ff7452715f4699a1d6a8991b 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -1720,8 +1720,20 @@ namespace __format
 	       basic_format_context<_Out, _CharT>& __fc) const
 	{
 	  if constexpr (numeric_limits<_Rep>::is_signed)
-	    if (__d < __d.zero())
-	      return _M_f._M_format(-__d, __fc, true);
+	    if (__d < __d.zero()) [[unlikely]]
+	      {
+		if constexpr (is_integral_v<_Rep>)
+		  {
+		    // -d is undefined for the most negative integer.
+		    // Convert duration to corresponding unsigned rep.
+		    using _URep = make_unsigned_t<_Rep>;
+		    auto __ucnt = -static_cast<_URep>(__d.count());
+		    auto __ud = chrono::duration<_URep, _Period>(__ucnt);
+		    return _M_f._M_format(__ud, __fc, true);
+		  }
+		else
+		  return _M_f._M_format(-__d, __fc, true);
+	      }
 	  return _M_f._M_format(__d, __fc, false);
 	}
 
diff --git a/libstdc++-v3/testsuite/20_util/duration/io.cc b/libstdc++-v3/testsuite/20_util/duration/io.cc
index 6b00689672c85254f2db75809cc280a836a9a845..57020f4f953767bf1fad7eca88d3caf9bb464834 100644
--- a/libstdc++-v3/testsuite/20_util/duration/io.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/io.cc
@@ -106,6 +106,14 @@ test_format()
   VERIFY( s == "500ms" );
   s = std::format("{:%Q %q}", u);
   VERIFY( s == "500 ms" );
+
+  // PR libstdc++/116755 extra minus sign for most negative value
+  auto minsec = std::chrono::seconds::min();
+  s = std::format("{}", minsec);
+  auto expected = std::format("{}s", minsec.count());
+  VERIFY( s == expected );
+  s = std::format("{:%Q%q}", minsec);
+  VERIFY( s == expected );
 }
 
 void