diff --git a/intl/components/src/TimeZone.h b/intl/components/src/TimeZone.h
index 180092bd3fc0b70462cc6ba67e72946e4c4c7604..2439e44997d859574bb4f40933e3bce90d2a56bc 100644
--- a/intl/components/src/TimeZone.h
+++ b/intl/components/src/TimeZone.h
@@ -106,23 +106,7 @@ class TimeZone final {
     mTimeZone->getDisplayName(static_cast<bool>(aDaylightSavings),
                               icu::TimeZone::LONG, icu::Locale(aLocale),
                               displayName);
-
-    int32_t length = displayName.length();
-    if (!aBuffer.reserve(AssertedCast<size_t>(length))) {
-      return Err(ICUError::OutOfMemory);
-    }
-
-    // Copy the display name.
-    UErrorCode status = U_ZERO_ERROR;
-    int32_t written = displayName.extract(aBuffer.data(), length, status);
-    if (!ICUSuccessForStringSpan(status)) {
-      return Err(ToICUError(status));
-    }
-    MOZ_ASSERT(written == length);
-
-    aBuffer.written(written);
-
-    return Ok{};
+    return FillBuffer(displayName, aBuffer);
 #else
     return FillBufferWithICUCall(
         aBuffer, [&](UChar* target, int32_t length, UErrorCode* status) {
@@ -134,6 +118,23 @@ class TimeZone final {
 #endif
   }
 
+  /**
+   * Return the identifier for this time zone.
+   */
+  template <typename B>
+  ICUResult GetId(B& aBuffer) {
+#if MOZ_INTL_USE_ICU_CPP_TIMEZONE
+    icu::UnicodeString id;
+    mTimeZone->getID(id);
+    return FillBuffer(id, aBuffer);
+#else
+    return FillBufferWithICUCall(
+        aBuffer, [&](UChar* target, int32_t length, UErrorCode* status) {
+          return ucal_getTimeZoneID(mCalendar, target, length, status);
+        });
+#endif
+  }
+
   /**
    * Fill the buffer with the system's default IANA time zone identifier, e.g.
    * "America/Chicago".
@@ -225,6 +226,25 @@ class TimeZone final {
   static Result<SpanEnumeration<char>, ICUError> GetAvailableTimeZones();
 
  private:
+  template <typename B>
+  static ICUResult FillBuffer(const icu::UnicodeString& aString, B& aBuffer) {
+    int32_t length = aString.length();
+    if (!aBuffer.reserve(AssertedCast<size_t>(length))) {
+      return Err(ICUError::OutOfMemory);
+    }
+
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t written = aString.extract(aBuffer.data(), length, status);
+    if (!ICUSuccessForStringSpan(status)) {
+      return Err(ToICUError(status));
+    }
+    MOZ_ASSERT(written == length);
+
+    aBuffer.written(written);
+
+    return Ok{};
+  }
+
 #if MOZ_INTL_USE_ICU_CPP_TIMEZONE
   UniquePtr<icu::TimeZone> mTimeZone = nullptr;
 #else
diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp
index 5a7774f136564097d7942f96d21dc4ea78717b40..7d9fa47b6b17c37e0fe32062c3eb668b47c3d96b 100644
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -107,6 +107,7 @@
 #include "util/Text.h"
 #include "vm/BooleanObject.h"
 #include "vm/DateObject.h"
+#include "vm/DateTime.h"
 #include "vm/ErrorObject.h"
 #include "vm/GlobalObject.h"
 #include "vm/HelperThreads.h"
@@ -7959,7 +7960,7 @@ static bool GetICUOptions(JSContext* cx, unsigned argc, Value* vp) {
 
   intl::FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> buf(cx);
 
-  if (auto ok = mozilla::intl::TimeZone::GetDefaultTimeZone(buf); ok.isErr()) {
+  if (auto ok = DateTimeInfo::timeZoneId(buf); ok.isErr()) {
     intl::ReportInternalError(cx, ok.unwrapErr());
     return false;
   }
diff --git a/js/src/builtin/intl/DateTimeFormat.cpp b/js/src/builtin/intl/DateTimeFormat.cpp
index bb5f259b9afb373f571d9f9a98ba54755159f7c9..893e6af31a85c7a6920ea0cb39acf5fa0436c697 100644
--- a/js/src/builtin/intl/DateTimeFormat.cpp
+++ b/js/src/builtin/intl/DateTimeFormat.cpp
@@ -402,13 +402,8 @@ bool js::intl_defaultTimeZone(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   MOZ_ASSERT(args.length() == 0);
 
-  // The current default might be stale, because JS::ResetTimeZone() doesn't
-  // immediately update ICU's default time zone. So perform an update if
-  // needed.
-  js::ResyncICUDefaultTimeZone();
-
   FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> timeZone(cx);
-  auto result = mozilla::intl::TimeZone::GetDefaultTimeZone(timeZone);
+  auto result = DateTimeInfo::timeZoneId(timeZone);
   if (result.isErr()) {
     intl::ReportInternalError(cx, result.unwrapErr());
     return false;
@@ -455,13 +450,8 @@ bool js::intl_isDefaultTimeZone(JSContext* cx, unsigned argc, Value* vp) {
     return true;
   }
 
-  // The current default might be stale, because JS::ResetTimeZone() doesn't
-  // immediately update ICU's default time zone. So perform an update if
-  // needed.
-  js::ResyncICUDefaultTimeZone();
-
   FormatBuffer<char16_t, intl::INITIAL_CHAR_BUFFER_SIZE> chars(cx);
-  auto result = mozilla::intl::TimeZone::GetDefaultTimeZone(chars);
+  auto result = DateTimeInfo::timeZoneId(chars);
   if (result.isErr()) {
     intl::ReportInternalError(cx, result.unwrapErr());
     return false;
diff --git a/js/src/vm/DateTime.cpp b/js/src/vm/DateTime.cpp
index cb3d1288c8b3f40fbcb40429381306c230960d76..6071d81dacf221445cead5d34d88d224d6dc7095 100644
--- a/js/src/vm/DateTime.cpp
+++ b/js/src/vm/DateTime.cpp
@@ -729,10 +729,6 @@ static bool ReadTimeZoneLink(std::string_view tz,
 #  endif /* defined(XP_WIN) */
 #endif   /* JS_HAS_INTL_API */
 
-void js::ResyncICUDefaultTimeZone() {
-  js::DateTimeInfo::resyncICUDefaultTimeZone();
-}
-
 void js::DateTimeInfo::internalResyncICUDefaultTimeZone() {
 #if JS_HAS_INTL_API
   if (const char* tzenv = std::getenv("TZ")) {
diff --git a/js/src/vm/DateTime.h b/js/src/vm/DateTime.h
index b70e4e0ae25947daed0079334956b8cabd5c52b7..efb20c392e7797ae9705dbf9ff8bc47056176de0 100644
--- a/js/src/vm/DateTime.h
+++ b/js/src/vm/DateTime.h
@@ -15,9 +15,8 @@
 #include "threading/ExclusiveData.h"
 
 #if JS_HAS_INTL_API
-namespace mozilla::intl {
-class TimeZone;
-}
+#  include "mozilla/intl/ICU4CGlue.h"
+#  include "mozilla/intl/TimeZone.h"
 #endif
 
 namespace js {
@@ -62,15 +61,6 @@ enum class ResetTimeZoneMode : bool {
  */
 extern void ResetTimeZoneInternal(ResetTimeZoneMode mode);
 
-/**
- * ICU's default time zone, used for various date/time formatting operations
- * that include the local time in the representation, is allowed to go stale
- * for unfortunate performance reasons.  Call this function when an up-to-date
- * default time zone is required, to resync ICU's default time zone with
- * reality.
- */
-extern void ResyncICUDefaultTimeZone();
-
 /**
  * Stores date/time information, particularly concerning the current local
  * time zone, and implements a small cache for daylight saving time offset
@@ -186,6 +176,16 @@ class DateTimeInfo {
     return guard->internalTimeZoneDisplayName(buf, buflen, utcMilliseconds,
                                               locale);
   }
+
+  /**
+   * Copy the identifier for the current time zone to the provided resizable
+   * buffer.
+   */
+  template <typename B>
+  static mozilla::intl::ICUResult timeZoneId(B& buffer) {
+    auto guard = acquireLockWithValidTimeZone();
+    return guard->timeZone()->GetId(buffer);
+  }
 #else
   /**
    * Return the local time zone adjustment (ES2019 20.3.1.7) as computed by
@@ -197,21 +197,14 @@ class DateTimeInfo {
 #endif /* JS_HAS_INTL_API */
 
  private:
-  // The two methods below should only be called via js::ResetTimeZoneInternal()
-  // and js::ResyncICUDefaultTimeZone().
+  // The method below should only be called via js::ResetTimeZoneInternal().
   friend void js::ResetTimeZoneInternal(ResetTimeZoneMode);
-  friend void js::ResyncICUDefaultTimeZone();
 
   static void resetTimeZone(ResetTimeZoneMode mode) {
     auto guard = instance->lock();
     guard->internalResetTimeZone(mode);
   }
 
-  static void resyncICUDefaultTimeZone() {
-    auto guard = acquireLockWithValidTimeZone();
-    (void)guard;
-  }
-
   struct RangeCache {
     // Start and end offsets in seconds describing the current and the
     // last cached range.