diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index 45e7d269e4b41a8f340e429357e805b1f2b337d4..bd21ec189a5ae1acbb6c9df91dc74619cc28a434 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -930,8 +930,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static constexpr weekday
       _S_from_days(const days& __d)
       {
-	auto __n = __d.count();
-	return weekday(__n >= -4 ? (__n + 4) % 7 : (__n + 5) % 7 + 6);
+	using _Rep = days::rep;
+	using _URep = make_unsigned_t<_Rep>;
+	const auto __n = __d.count();
+	const auto __m = static_cast<_URep>(__n);
+
+	// 1970-01-01 (__n =  0, __m = 0        ) -> Thursday (4)
+	// 1969-31-12 (__n = -1, __m = _URep(-1)) -> Wednesday (3)
+	const auto __offset = __n >= 0 ? _URep(4) : 3 - _URep(-1) % 7 - 7;
+	return weekday((__m + __offset) % 7);
       }
 
     public:
diff --git a/libstdc++-v3/testsuite/std/time/weekday/1.cc b/libstdc++-v3/testsuite/std/time/weekday/1.cc
index 00278c8b01cb873f37b3959f5d75ce8483267c1f..e89fca47d4b64b35a5a74d3232567f4b12053a6c 100644
--- a/libstdc++-v3/testsuite/std/time/weekday/1.cc
+++ b/libstdc++-v3/testsuite/std/time/weekday/1.cc
@@ -20,6 +20,7 @@
 // Class template day [time.cal.weekday]
 
 #include <chrono>
+#include <limits>
 
 constexpr void
 constexpr_weekday()
@@ -37,6 +38,14 @@ constexpr_weekday()
   static_assert(weekday{3}[2].weekday() == weekday{3});
   static_assert(weekday{3}[last].weekday() == weekday{3});
 
+  // Test for UB (overflow).
+  {
+    using rep = days::rep;
+    using std::numeric_limits;
+    constexpr weekday max{sys_days{days{numeric_limits<rep>::max()}}};
+    constexpr weekday min{sys_days{days{numeric_limits<rep>::min()}}};
+  }
+
   static_assert(weekday{sys_days{1900y/January/1}} == Monday);
   static_assert(weekday{sys_days{1970y/January/1}} == Thursday);
   static_assert(weekday{sys_days{2020y/August/21}} == Friday);