diff --git a/src/java.base/share/classes/java/time/LocalDateTime.java b/src/java.base/share/classes/java/time/LocalDateTime.java
index d14afb7d78f..cea9123258c 100644
--- a/src/java.base/share/classes/java/time/LocalDateTime.java
+++ b/src/java.base/share/classes/java/time/LocalDateTime.java
@@ -1966,10 +1966,17 @@ public final class LocalDateTime
     @Override
     public String toString() {
         var buf = new StringBuilder(29);
+        formatTo(buf);
+        return buf.toString();
+    }
+
+    /**
+     * Prints the toString result to the given buf, avoiding extra string allocations.
+     */
+    void formatTo(StringBuilder buf) {
         date.formatTo(buf);
         buf.append('T');
         time.formatTo(buf);
-        return buf.toString();
     }
 
     //-----------------------------------------------------------------------
diff --git a/src/java.base/share/classes/java/time/OffsetDateTime.java b/src/java.base/share/classes/java/time/OffsetDateTime.java
index bd75fffb24e..fd8355e36cd 100644
--- a/src/java.base/share/classes/java/time/OffsetDateTime.java
+++ b/src/java.base/share/classes/java/time/OffsetDateTime.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1923,7 +1923,10 @@ public final class OffsetDateTime
      */
     @Override
     public String toString() {
-        return dateTime.toString() + offset.toString();
+        var offsetStr = offset.toString();
+        var buf = new StringBuilder(29 + offsetStr.length());
+        dateTime.formatTo(buf);
+        return buf.append(offsetStr).toString();
     }
 
     //-----------------------------------------------------------------------
diff --git a/src/java.base/share/classes/java/time/OffsetTime.java b/src/java.base/share/classes/java/time/OffsetTime.java
index b9fe5e533d8..1f6feb4180f 100644
--- a/src/java.base/share/classes/java/time/OffsetTime.java
+++ b/src/java.base/share/classes/java/time/OffsetTime.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1398,7 +1398,10 @@ public final class OffsetTime
      */
     @Override
     public String toString() {
-        return time.toString() + offset.toString();
+        var offsetStr = offset.toString();
+        var buf = new StringBuilder(18 + offsetStr.length());
+        time.formatTo(buf);
+        return buf.append(offsetStr).toString();
     }
 
     //-----------------------------------------------------------------------
diff --git a/src/java.base/share/classes/java/time/ZonedDateTime.java b/src/java.base/share/classes/java/time/ZonedDateTime.java
index 555392cf513..b1426efc914 100644
--- a/src/java.base/share/classes/java/time/ZonedDateTime.java
+++ b/src/java.base/share/classes/java/time/ZonedDateTime.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2214,11 +2214,20 @@ public final class ZonedDateTime
      */
     @Override  // override for Javadoc
     public String toString() {
-        String str = dateTime.toString() + offset.toString();
+        var offsetStr = offset.toString();
+        var zoneStr = (String) null;
+        int length = 29 + offsetStr.length();
         if (offset != zone) {
-            str += '[' + zone.toString() + ']';
+            zoneStr = zone.toString();
+            length += zoneStr.length() + 2;
         }
-        return str;
+        var buf = new StringBuilder(length);
+        dateTime.formatTo(buf);
+        buf.append(offsetStr);
+        if (zoneStr != null) {
+            buf.append('[').append(zoneStr).append(']');
+        }
+        return buf.toString();
     }
 
     //-----------------------------------------------------------------------