Update datetime_format API in intl4x
diff --git a/pkgs/intl4x/example/docs/datetime_format.dart b/pkgs/intl4x/example/docs/datetime_format.dart
index 04a0602..9576779 100644
--- a/pkgs/intl4x/example/docs/datetime_format.dart
+++ b/pkgs/intl4x/example/docs/datetime_format.dart
@@ -8,12 +8,22 @@
   // #region datetime_format
   final timeZone = 'Europe/Paris';
   final dateTime = DateTime.parse('2024-07-01T08:50:07');
-  final formatter = DateTimeFormat.yearMonthDayTime(
+  // Showcase dot shorthand
+  // ignore: omit_local_variable_types
+  final DateTimeFormat formatter = .yearMonthDayTime(
     locale: Locale.parse('en'),
     length: DateTimeLength.long,
-  ).withTimeZoneLong();
+  );
   print(
-    formatter.format(dateTime, timeZone),
+    formatter.withTimeZoneLong().format(dateTime, timeZone),
   ); // July 1, 2024 at 8:50:07 AM Central European Summer Time
   // #endregion datetime_format
+
+  final formatter2 = DateTimeFormat.month(
+    locale: Locale.parse('en'),
+    length: DateTimeLength.long,
+  );
+  print(
+    formatter2.format(dateTime),
+  ); // July 1, 2024 at 8:50:07 AM Central European Summer Time
 }
diff --git a/pkgs/intl4x/lib/datetime_format.dart b/pkgs/intl4x/lib/datetime_format.dart
index 4b3ed68..4efcadc 100644
--- a/pkgs/intl4x/lib/datetime_format.dart
+++ b/pkgs/intl4x/lib/datetime_format.dart
@@ -22,19 +22,22 @@
 /// * [DateTimeFormat.time]
 ///
 /// and the zoned variants through
-/// * [ZoneableDateTimeFormat.withTimeZoneShort]
-/// * [ZoneableDateTimeFormat.withTimeZoneLong]
-/// * [ZoneableDateTimeFormat.withTimeZoneShortOffset]
-/// * [ZoneableDateTimeFormat.withTimeZoneLongOffset]
-/// * [ZoneableDateTimeFormat.withTimeZoneShortGeneric]
-/// * [ZoneableDateTimeFormat.withTimeZoneLongGeneric]
+/// * [DateTimeFormat.withTimeZoneShort]
+/// * [DateTimeFormat.withTimeZoneLong]
+/// * [DateTimeFormat.withTimeZoneShortOffset]
+/// * [DateTimeFormat.withTimeZoneLongOffset]
+/// * [DateTimeFormat.withTimeZoneShortGeneric]
+/// * [DateTimeFormat.withTimeZoneLongGeneric]
 library;
 
-import 'src/datetime_format/datetime_format.dart'
-    show DateTimeFormat, ZoneableDateTimeFormat;
+import 'src/datetime_format/datetime_format.dart' show DateTimeFormat;
 
 export 'src/datetime_format/datetime_format.dart'
-    show DateTimeFormat, ZoneableDateTimeFormat;
+    show
+        DateTimeFormat,
+        DateTimeFormatUnzoneable,
+        DateTimeFormattable,
+        TimeZoneable;
 export 'src/datetime_format/datetime_format_impl.dart' show ZonedDateTimeFormat;
 export 'src/datetime_format/datetime_format_options.dart'
     show
diff --git a/pkgs/intl4x/lib/src/datetime_format/datetime_format.dart b/pkgs/intl4x/lib/src/datetime_format/datetime_format.dart
index 79e9ff5..7fdbea3 100644
--- a/pkgs/intl4x/lib/src/datetime_format/datetime_format.dart
+++ b/pkgs/intl4x/lib/src/datetime_format/datetime_format.dart
@@ -2,4 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-export 'datetime_format_impl.dart' show DateTimeFormat, ZoneableDateTimeFormat;
+export 'datetime_format_impl.dart'
+    show
+        DateTimeFormat,
+        DateTimeFormatUnzoneable,
+        DateTimeFormattable,
+        TimeZoneable;
diff --git a/pkgs/intl4x/lib/src/datetime_format/datetime_format_ecma.dart b/pkgs/intl4x/lib/src/datetime_format/datetime_format_ecma.dart
index 95d5c4a..9b557d3 100644
--- a/pkgs/intl4x/lib/src/datetime_format/datetime_format_ecma.dart
+++ b/pkgs/intl4x/lib/src/datetime_format/datetime_format_ecma.dart
@@ -105,63 +105,24 @@
   const _MonthStyle([this._jsName]);
 }
 
-class _FormatECMA extends FormatImpl {
-  final Locale locale;
-  final DateTimeFormatImpl impl;
-  final _DateTimeFormat dateTimeFormat;
-
-  _FormatECMA._(this.impl, _DateTimeJSOptions _optionsJS, this.locale)
-    : dateTimeFormat = _DateTimeFormat(
-        [locale.toLanguageTag().toJS].toJS,
-        _optionsJS,
-      ),
-      super(impl);
-
-  @override
-  String formatInternal(DateTime datetime) =>
-      dateTimeFormat.format(datetime.js);
-}
-
-class _FormatterECMA extends FormatterImpl {
+class _FormatterECMA implements FormatterImpl {
   final Locale locale;
   final _DateTimeJSOptions _optionsJS;
   final DateTimeFormatImpl impl;
   final _DateTimeFormat dateTimeFormat;
 
-  _FormatterECMA._(this.impl, this._optionsJS, this.locale)
+  _FormatterECMA(this.impl, this._optionsJS, this.locale)
     : dateTimeFormat = _DateTimeFormat(
         [locale.toLanguageTag().toJS].toJS,
         _optionsJS,
-      ),
-      super(impl);
+      );
 
   @override
-  String formatInternal(DateTime datetime) =>
-      dateTimeFormat.format(datetime.js);
+  String format(DateTime datetime) => dateTimeFormat.format(datetime.js);
 
   @override
-  ZonedDateTimeFormat withTimeZoneLong() =>
-      _FormatterZonedECMA(TimeZoneType.long, this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLongGeneric() =>
-      _FormatterZonedECMA(TimeZoneType.longGeneric, this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLongOffset() =>
-      _FormatterZonedECMA(TimeZoneType.longOffset, this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShort() =>
-      _FormatterZonedECMA(TimeZoneType.short, this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShortGeneric() =>
-      _FormatterZonedECMA(TimeZoneType.shortGeneric, this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShortOffset() =>
-      _FormatterZonedECMA(TimeZoneType.shortOffset, this);
+  ZonedDateTimeFormat withTimeZone(TimeZoneType timeZoneType) =>
+      _FormatterZonedECMA(timeZoneType, this);
 }
 
 class _FormatterZonedECMA extends FormatterZonedImpl {
@@ -226,25 +187,25 @@
 
   @override
   FormatterImpl d({DateTimeAlignment? alignment, DateTimeLength? length}) =>
-      _FormatterECMA._(
+      _FormatterECMA(
         this,
         _DateTimeJSOptions.from(day: _dayStyleD(alignment)),
         locale,
       );
 
   @override
-  FormatterImpl e({DateTimeLength? length}) => _FormatterECMA._(
+  FormatterImpl e({DateTimeLength? length}) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(weekday: _weekday(length)),
     locale,
   );
 
   @override
-  FormatImpl m({
+  FormatterImpl m({
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     bool standalone = true,
-  }) => _FormatECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(month: _monthStyle(alignment, length)),
     locale,
@@ -252,7 +213,7 @@
 
   @override
   FormatterImpl md({DateTimeAlignment? alignment, DateTimeLength? length}) =>
-      _FormatterECMA._(
+      _FormatterECMA(
         this,
         _DateTimeJSOptions.from(
           month: _monthStyle(alignment, length),
@@ -263,7 +224,7 @@
 
   @override
   FormatterImpl mde({DateTimeAlignment? alignment, DateTimeLength? length}) =>
-      _FormatterECMA._(
+      _FormatterECMA(
         this,
         _DateTimeJSOptions.from(
           month: _monthStyle(alignment, length),
@@ -278,7 +239,7 @@
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     TimePrecision? timePrecision,
-  }) => _FormatterECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(
       hour: _dayStyleD(alignment),
@@ -290,11 +251,11 @@
   );
 
   @override
-  FormatImpl y({
+  FormatterImpl y({
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => _FormatECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(
       year: _yearStyle(length, alignment, yearStyle),
@@ -308,7 +269,7 @@
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => _FormatterECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(
       year: _yearStyle(length, alignment, yearStyle),
@@ -323,7 +284,7 @@
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => _FormatterECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(
       year: _yearStyle(length, alignment, yearStyle),
@@ -339,7 +300,7 @@
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => _FormatterECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(
       year: _yearStyle(length, alignment, yearStyle),
@@ -356,7 +317,7 @@
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     TimePrecision? timePrecision,
-  }) => _FormatterECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(
       hour: _dayStyleD(alignment),
@@ -375,7 +336,7 @@
     DateTimeLength? length,
     TimePrecision? timePrecision,
     YearStyle? yearStyle,
-  }) => _FormatterECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(
       hour: _dayStyleD(alignment),
@@ -396,7 +357,7 @@
     DateTimeLength? length,
     TimePrecision? timePrecision,
     YearStyle? yearStyle,
-  }) => _FormatterECMA._(
+  }) => _FormatterECMA(
     this,
     _DateTimeJSOptions.from(
       hour: _dayStyleD(alignment),
diff --git a/pkgs/intl4x/lib/src/datetime_format/datetime_format_impl.dart b/pkgs/intl4x/lib/src/datetime_format/datetime_format_impl.dart
index 1888fd4..028e3a1 100644
--- a/pkgs/intl4x/lib/src/datetime_format/datetime_format_impl.dart
+++ b/pkgs/intl4x/lib/src/datetime_format/datetime_format_impl.dart
@@ -30,13 +30,13 @@
 
   FormatterImpl e({DateTimeLength? length});
 
-  FormatImpl m({DateTimeAlignment? alignment, DateTimeLength? length});
+  FormatterImpl m({DateTimeAlignment? alignment, DateTimeLength? length});
 
   FormatterImpl md({DateTimeAlignment? alignment, DateTimeLength? length});
 
   FormatterImpl mde({DateTimeAlignment? alignment, DateTimeLength? length});
 
-  FormatImpl y({
+  FormatterImpl y({
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
@@ -87,26 +87,35 @@
   });
 }
 
-abstract class FormatImpl extends DateTimeFormat {
-  final DateTimeFormatImpl _impl;
+abstract interface class FormatterImpl {
+  String format(DateTime datetime);
+  ZonedDateTimeFormat withTimeZone(TimeZoneType timeZoneType);
+}
 
-  FormatImpl(this._impl);
+abstract class DateTimeFormattable {
+  final FormatterImpl _impl;
+  final Locale _locale;
 
-  String formatInternal(DateTime datetime);
+  DateTimeFormattable(this._impl, this._locale);
 
-  @override
   String format(DateTime datetime) {
     if (isInTest) {
-      return '$datetime//${_impl.locale}';
+      return '$datetime//$_locale';
     } else {
-      return formatInternal(datetime);
+      return _impl.format(datetime);
     }
   }
 }
 
-abstract class FormatterImpl extends FormatImpl
-    implements ZoneableDateTimeFormat {
-  FormatterImpl(super.impl);
+mixin TimeZoneable {
+  ZonedDateTimeFormat withTimeZoneShort();
+  ZonedDateTimeFormat withTimeZoneLong();
+  ZonedDateTimeFormat withTimeZoneShortOffset();
+  ZonedDateTimeFormat withTimeZoneLongOffset();
+  ZonedDateTimeFormat withTimeZoneShortGeneric();
+  ZonedDateTimeFormat withTimeZoneLongGeneric();
+
+  ZonedDateTimeFormat withTZLong() => withTimeZoneLong();
 }
 
 abstract class FormatterZonedImpl extends ZonedDateTimeFormat {
@@ -129,9 +138,9 @@
 
 /// A base class for formatters that can format a [DateTime] into a string.
 ///
-/// Most formatters are [ZoneableDateTimeFormat]s that can also format with time
-/// zone information. Only the formatters for year and month are standalone and
-/// do not support time zones, returning [DateTimeFormat].
+/// Most formatters are [DateTimeFormat]s that can also format with time
+/// zone information. Formatters for year and month are
+/// [DateTimeFormatUnzoneable] and do not support time zones.
 ///
 /// Example:
 /// ```dart
@@ -141,10 +150,32 @@
 ///   print(DateTimeFormat.year().format(date)); // Output: '2021'
 /// }
 /// ```
-sealed class DateTimeFormat {
-  /// Formats the given [datetime] into a string according to the formatter's
-  /// configured locale and options.
-  String format(DateTime datetime);
+class DateTimeFormat extends DateTimeFormattable with TimeZoneable {
+  DateTimeFormat._(super._impl, super._locale);
+
+  @override
+  ZonedDateTimeFormat withTimeZoneShort() =>
+      _impl.withTimeZone(TimeZoneType.short);
+
+  @override
+  ZonedDateTimeFormat withTimeZoneLong() =>
+      _impl.withTimeZone(TimeZoneType.long);
+
+  @override
+  ZonedDateTimeFormat withTimeZoneShortOffset() =>
+      _impl.withTimeZone(TimeZoneType.shortOffset);
+
+  @override
+  ZonedDateTimeFormat withTimeZoneLongOffset() =>
+      _impl.withTimeZone(TimeZoneType.longOffset);
+
+  @override
+  ZonedDateTimeFormat withTimeZoneShortGeneric() =>
+      _impl.withTimeZone(TimeZoneType.shortGeneric);
+
+  @override
+  ZonedDateTimeFormat withTimeZoneLongGeneric() =>
+      _impl.withTimeZone(TimeZoneType.longGeneric);
 
   /// Formatting just the day.
   ///
@@ -157,13 +188,16 @@
   ///   print(DateTimeFormat.day().format(date)); // Output: '17'
   /// }
   /// ```
-  static ZoneableDateTimeFormat day({
+  static DateTimeFormat day({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
-  }) => DateTimeFormatImpl.build(
+  }) => DateTimeFormat._(
+    DateTimeFormatImpl.build(
+      locale ?? findSystemLocale(),
+    ).d(alignment: alignment, length: length),
     locale ?? findSystemLocale(),
-  ).d(alignment: alignment, length: length);
+  );
 
   /// Formatting just the weekday.
   ///
@@ -176,11 +210,11 @@
   ///   print(DateTimeFormat.weekday().format(date)); // Output: 'Friday'
   /// }
   /// ```
-  static ZoneableDateTimeFormat weekday({
-    Locale? locale,
-    DateTimeLength? length,
-  }) =>
-      DateTimeFormatImpl.build(locale ?? findSystemLocale()).e(length: length);
+  static DateTimeFormat weekday({Locale? locale, DateTimeLength? length}) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(impl.e(length: length), loc);
+  }
 
   /// Formatting just the month.
   ///
@@ -193,13 +227,18 @@
   ///   print(DateTimeFormat.month().format(date)); // Output: 'Dec'
   /// }
   /// ```
-  static DateTimeFormat month({
+  static DateTimeFormatUnzoneable month({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).m(alignment: alignment, length: length);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormatUnzoneable._(
+      impl.m(alignment: alignment, length: length),
+      loc,
+    );
+  }
 
   /// Formatting the month and day.
   ///
@@ -212,13 +251,15 @@
   ///   print(DateTimeFormat.monthDay().format(date)); // Output: 'Dec 17'
   /// }
   /// ```
-  static ZoneableDateTimeFormat monthDay({
+  static DateTimeFormat monthDay({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).md(alignment: alignment, length: length);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(impl.md(alignment: alignment, length: length), loc);
+  }
 
   /// Formatting the month, day, and weekday.
   ///
@@ -231,13 +272,18 @@
   ///   print(DateTimeFormat.monthDayWeekday().format(date)); // Output: 'Fri, Dec 17'
   /// }
   /// ```
-  static ZoneableDateTimeFormat monthDayWeekday({
+  static DateTimeFormat monthDayWeekday({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).mde(alignment: alignment, length: length);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(
+      impl.mde(alignment: alignment, length: length),
+      loc,
+    );
+  }
 
   /// Formatting just the year.
   ///
@@ -250,14 +296,19 @@
   ///   print(DateTimeFormat.year().format(date)); // Output: '2021'
   /// }
   /// ```
-  static DateTimeFormat year({
+  static DateTimeFormatUnzoneable year({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).y(alignment: alignment, length: length, yearStyle: yearStyle);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormatUnzoneable._(
+      impl.y(alignment: alignment, length: length, yearStyle: yearStyle),
+      loc,
+    );
+  }
 
   /// Formatting the year and month.
   ///
@@ -270,14 +321,19 @@
   ///   print(DateTimeFormat.yearMonth().format(date)); // Output: 'Dec 2021'
   /// }
   /// ```
-  static ZoneableDateTimeFormat yearMonth({
+  static DateTimeFormat yearMonth({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).ym(alignment: alignment, length: length, yearStyle: yearStyle);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(
+      impl.ym(alignment: alignment, length: length, yearStyle: yearStyle),
+      loc,
+    );
+  }
 
   /// Formatting the year, month, and day.
   ///
@@ -290,14 +346,19 @@
   ///   print(DateTimeFormat.yearMonthDay().format(date)); // Output: 'Dec 17, 2021'
   /// }
   /// ```
-  static ZoneableDateTimeFormat yearMonthDay({
+  static DateTimeFormat yearMonthDay({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).ymd(alignment: alignment, length: length, yearStyle: yearStyle);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(
+      impl.ymd(alignment: alignment, length: length, yearStyle: yearStyle),
+      loc,
+    );
+  }
 
   /// Formatting the year, month, day, and weekday.
   ///
@@ -310,14 +371,19 @@
   ///   print(DateTimeFormat.yearMonthDayWeekday().format(date)); // Output: 'Fri, Dec 17, 2021'
   /// }
   /// ```
-  static ZoneableDateTimeFormat yearMonthDayWeekday({
+  static DateTimeFormat yearMonthDayWeekday({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).ymde(alignment: alignment, length: length, yearStyle: yearStyle);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(
+      impl.ymde(alignment: alignment, length: length, yearStyle: yearStyle),
+      loc,
+    );
+  }
 
   /// Formatting the month, day, and time.
   ///
@@ -330,14 +396,23 @@
   ///   print(DateTimeFormat.monthDayTime().format(date)); // Output: 'Dec 17, 4:00 AM'
   /// }
   /// ```
-  static ZoneableDateTimeFormat monthDayTime({
+  static DateTimeFormat monthDayTime({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     TimePrecision? timePrecision,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).mdt(alignment: alignment, length: length, timePrecision: timePrecision);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(
+      impl.mdt(
+        alignment: alignment,
+        length: length,
+        timePrecision: timePrecision,
+      ),
+      loc,
+    );
+  }
 
   /// Formatting the year, month, day, and time.
   ///
@@ -350,18 +425,25 @@
   ///   print(DateTimeFormat.yearMonthDayTime().format(date)); // Output: 'Dec 17, 2021, 4:00 AM'
   /// }
   /// ```
-  static ZoneableDateTimeFormat yearMonthDayTime({
+  static DateTimeFormat yearMonthDayTime({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     TimePrecision? timePrecision,
     YearStyle? yearStyle,
-  }) => DateTimeFormatImpl.build(locale ?? findSystemLocale()).ymdt(
-    alignment: alignment,
-    length: length,
-    timePrecision: timePrecision,
-    yearStyle: yearStyle,
-  );
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(
+      impl.ymdt(
+        alignment: alignment,
+        length: length,
+        timePrecision: timePrecision,
+        yearStyle: yearStyle,
+      ),
+      loc,
+    );
+  }
 
   /// Formatting the year, month, day, weekday, and time.
   ///
@@ -374,18 +456,25 @@
   ///   print(DateTimeFormat.yearMonthDayWeekdayTime().format(date)); // Output: 'Fri, Dec 17, 2021, 4:00 AM'
   /// }
   /// ```
-  static ZoneableDateTimeFormat yearMonthDayWeekdayTime({
+  static DateTimeFormat yearMonthDayWeekdayTime({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     TimePrecision? timePrecision,
     YearStyle? yearStyle,
-  }) => DateTimeFormatImpl.build(locale ?? findSystemLocale()).ymdet(
-    alignment: alignment,
-    length: length,
-    timePrecision: timePrecision,
-    yearStyle: yearStyle,
-  );
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(
+      impl.ymdet(
+        alignment: alignment,
+        length: length,
+        timePrecision: timePrecision,
+        yearStyle: yearStyle,
+      ),
+      loc,
+    );
+  }
 
   /// Formatting just the time.
   ///
@@ -398,53 +487,27 @@
   ///   print(DateTimeFormat.time().format(date)); // Output: '4:00 AM'
   /// }
   /// ```
-  static ZoneableDateTimeFormat time({
+  static DateTimeFormat time({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     TimePrecision? timePrecision,
-  }) => DateTimeFormatImpl.build(
-    locale ?? findSystemLocale(),
-  ).t(alignment: alignment, length: length, timePrecision: timePrecision);
+  }) {
+    final loc = locale ?? findSystemLocale();
+    final impl = DateTimeFormatImpl.build(loc);
+    return DateTimeFormat._(
+      impl.t(
+        alignment: alignment,
+        length: length,
+        timePrecision: timePrecision,
+      ),
+      loc,
+    );
+  }
 }
 
-/// Formatters that can format a [DateTime] with time zone information.
-///
-/// This class extends [DateTimeFormat] and provides additional
-/// methods to format dates and times with time zone information.
-///
-/// Example:
-/// ```dart
-/// import 'package:intl4x/datetime_format.dart';
-/// void main() {
-///   final date = DateTime(2021, 12, 17, 4, 0, 42);
-///   print(DateTimeFormat.year().format(date)); // Output: '2021'
-/// }
-/// ```
-sealed class ZoneableDateTimeFormat extends DateTimeFormat {
-  /// Returns a [ZonedDateTimeFormat] that formats the datetime with a
-  /// short time zone name.
-  ZonedDateTimeFormat withTimeZoneShort();
-
-  /// Returns a [ZonedDateTimeFormat] that formats the datetime with a
-  /// long time zone name.
-  ZonedDateTimeFormat withTimeZoneLong();
-
-  /// Returns a [ZonedDateTimeFormat] that formats the datetime with a
-  /// short localized GMT format (e.g. "GMT-8").
-  ZonedDateTimeFormat withTimeZoneShortOffset();
-
-  /// Returns a [ZonedDateTimeFormat] that formats the datetime with a
-  /// long localized GMT format (e.g. "GMT-08:00").
-  ZonedDateTimeFormat withTimeZoneLongOffset();
-
-  /// Returns a [ZonedDateTimeFormat] that formats the datetime with a
-  /// short generic non-location format (e.g. "PT").
-  ZonedDateTimeFormat withTimeZoneShortGeneric();
-
-  /// Returns a [ZonedDateTimeFormat] that formats the datetime with a
-  /// long generic non-location format (e.g. "Pacific Time").
-  ZonedDateTimeFormat withTimeZoneLongGeneric();
+class DateTimeFormatUnzoneable extends DateTimeFormattable {
+  DateTimeFormatUnzoneable._(super._impl, super._locale);
 }
 
 /// A base class for formatters that can format a [DateTime] and time zone
diff --git a/pkgs/intl4x/lib/src/datetime_format/icu4x/date_formatter.dart b/pkgs/intl4x/lib/src/datetime_format/icu4x/date_formatter.dart
index 5fe1ea8..3d3f37c 100644
--- a/pkgs/intl4x/lib/src/datetime_format/icu4x/date_formatter.dart
+++ b/pkgs/intl4x/lib/src/datetime_format/icu4x/date_formatter.dart
@@ -9,7 +9,7 @@
 import 'datetime_format_4x.dart';
 
 /// Wraps an [icu.DateFormatter]
-class DateFormatterX extends FormatterImpl {
+class DateFormatterX implements FormatterImpl {
   final icu.DateFormatter formatter;
   final DateTimeFormatImpl impl;
   final icu.Locale localeX;
@@ -23,8 +23,7 @@
         localeX,
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
-      ),
-      super(impl);
+      );
 
   DateFormatterX.m(
     this.impl,
@@ -35,8 +34,7 @@
         localeX,
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
-      ),
-      super(impl);
+      );
 
   DateFormatterX.md(
     this.impl,
@@ -47,12 +45,10 @@
         localeX,
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
-      ),
-      super(impl);
+      );
 
   DateFormatterX.e(this.impl, this.localeX, icu.DateTimeLength? length)
-    : formatter = icu.DateFormatter.e(localeX, length),
-      super(impl);
+    : formatter = icu.DateFormatter.e(localeX, length);
 
   DateFormatterX.mde(
     this.impl,
@@ -63,8 +59,7 @@
         localeX,
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
-      ),
-      super(impl);
+      );
 
   DateFormatterX.ym(
     this.impl,
@@ -77,8 +72,7 @@
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
         yearStyle: yearStyle,
-      ),
-      super(impl);
+      );
 
   DateFormatterX.y(
     this.impl,
@@ -91,8 +85,7 @@
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
         yearStyle: yearStyle,
-      ),
-      super(impl);
+      );
 
   DateFormatterX.ymd(
     this.impl,
@@ -105,8 +98,7 @@
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
         yearStyle: yearStyle,
-      ),
-      super(impl);
+      );
 
   DateFormatterX.ymde(
     this.impl,
@@ -119,71 +111,21 @@
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
         yearStyle: yearStyle,
-      ),
-      super(impl);
+      );
 
   @override
-  String formatInternal(DateTime datetime) =>
-      formatter.formatIso(datetime.toX.$1);
+  String format(DateTime datetime) => formatter.formatIso(datetime.toX.$1);
 
   @override
-  ZonedDateTimeFormat withTimeZoneShort() => DateFormatterZonedX.short(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLong() => DateFormatterZonedX.long(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShortOffset() =>
-      DateFormatterZonedX.shortOffset(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLongOffset() =>
-      DateFormatterZonedX.longOffset(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShortGeneric() =>
-      DateFormatterZonedX.shortGeneric(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLongGeneric() =>
-      DateFormatterZonedX.longGeneric(this);
-}
-
-/// Wraps an [icu.DateFormatter]
-class DateFormatterUX extends FormatImpl {
-  final icu.DateFormatter formatter;
-  final DateTimeFormatImpl impl;
-  final icu.Locale localeX;
-
-  DateFormatterUX.m(
-    this.impl,
-    this.localeX,
-    icu.DateTimeAlignment? alignment,
-    icu.DateTimeLength? length,
-  ) : formatter = icu.DateFormatter.m(
-        localeX,
-        alignment: alignment,
-        length: length ?? icu.DateTimeLength.short,
-      ),
-      super(impl);
-
-  DateFormatterUX.y(
-    this.impl,
-    this.localeX,
-    icu.DateTimeAlignment? alignment,
-    icu.DateTimeLength? length,
-    icu.YearStyle? yearStyle,
-  ) : formatter = icu.DateFormatter.y(
-        localeX,
-        alignment: alignment,
-        length: length ?? icu.DateTimeLength.short,
-        yearStyle: yearStyle,
-      ),
-      super(impl);
-
-  @override
-  String formatInternal(DateTime datetime) =>
-      formatter.formatIso(datetime.toX.$1);
+  ZonedDateTimeFormat withTimeZone(TimeZoneType timeZoneType) =>
+      switch (timeZoneType) {
+        TimeZoneType.short => DateFormatterZonedX.short(this),
+        TimeZoneType.long => DateFormatterZonedX.long(this),
+        TimeZoneType.shortOffset => DateFormatterZonedX.shortOffset(this),
+        TimeZoneType.longOffset => DateFormatterZonedX.longOffset(this),
+        TimeZoneType.shortGeneric => DateFormatterZonedX.shortGeneric(this),
+        TimeZoneType.longGeneric => DateFormatterZonedX.longGeneric(this),
+      };
 }
 
 /// Wraps an [icu.ZonedDateFormatter]
diff --git a/pkgs/intl4x/lib/src/datetime_format/icu4x/date_time_formatter.dart b/pkgs/intl4x/lib/src/datetime_format/icu4x/date_time_formatter.dart
index c8685cf..0c31ebd 100644
--- a/pkgs/intl4x/lib/src/datetime_format/icu4x/date_time_formatter.dart
+++ b/pkgs/intl4x/lib/src/datetime_format/icu4x/date_time_formatter.dart
@@ -9,7 +9,7 @@
 import 'datetime_format_4x.dart';
 
 /// Wraps an [icu.DateTimeFormatter]
-class DateTimeFormatterX extends FormatterImpl {
+class DateTimeFormatterX implements FormatterImpl {
   final icu.DateTimeFormatter formatter;
   final DateTimeFormatImpl impl;
   final icu.Locale localeX;
@@ -25,8 +25,7 @@
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
         timePrecision: timePrecision,
-      ),
-      super(impl);
+      );
 
   DateTimeFormatterX.ymdt(
     this.impl,
@@ -41,8 +40,7 @@
         length: length ?? icu.DateTimeLength.short,
         timePrecision: timePrecision,
         yearStyle: yearStyle,
-      ),
-      super(impl);
+      );
 
   DateTimeFormatterX.ymdet(
     this.impl,
@@ -57,37 +55,24 @@
         length: length ?? icu.DateTimeLength.short,
         timePrecision: timePrecision,
         yearStyle: yearStyle,
-      ),
-      super(impl);
+      );
 
   @override
-  String formatInternal(DateTime datetime) {
+  String format(DateTime datetime) {
     final (isoDate, time) = datetime.toX;
     return formatter.formatIso(isoDate, time);
   }
 
   @override
-  ZonedDateTimeFormat withTimeZoneShort() =>
-      DateTimeFormatterZonedX.short(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLong() => DateTimeFormatterZonedX.long(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShortOffset() =>
-      DateTimeFormatterZonedX.shortOffset(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLongOffset() =>
-      DateTimeFormatterZonedX.longOffset(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShortGeneric() =>
-      DateTimeFormatterZonedX.shortGeneric(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLongGeneric() =>
-      DateTimeFormatterZonedX.longGeneric(this);
+  ZonedDateTimeFormat withTimeZone(TimeZoneType timeZoneType) =>
+      switch (timeZoneType) {
+        TimeZoneType.short => DateTimeFormatterZonedX.short(this),
+        TimeZoneType.long => DateTimeFormatterZonedX.long(this),
+        TimeZoneType.shortOffset => DateTimeFormatterZonedX.shortOffset(this),
+        TimeZoneType.longOffset => DateTimeFormatterZonedX.longOffset(this),
+        TimeZoneType.shortGeneric => DateTimeFormatterZonedX.shortGeneric(this),
+        TimeZoneType.longGeneric => DateTimeFormatterZonedX.longGeneric(this),
+      };
 }
 
 /// Wraps an [icu.ZonedDateTimeFormatter]
diff --git a/pkgs/intl4x/lib/src/datetime_format/icu4x/datetime_format_4x.dart b/pkgs/intl4x/lib/src/datetime_format/icu4x/datetime_format_4x.dart
index 80d5436..739676f 100644
--- a/pkgs/intl4x/lib/src/datetime_format/icu4x/datetime_format_4x.dart
+++ b/pkgs/intl4x/lib/src/datetime_format/icu4x/datetime_format_4x.dart
@@ -36,8 +36,8 @@
       DateFormatterX.e(this, localeX, length?.toX);
 
   @override
-  FormatImpl m({DateTimeAlignment? alignment, DateTimeLength? length}) =>
-      DateFormatterUX.m(this, localeX, alignment?.toX, length?.toX);
+  FormatterImpl m({DateTimeAlignment? alignment, DateTimeLength? length}) =>
+      DateFormatterX.m(this, localeX, alignment?.toX, length?.toX);
 
   @override
   FormatterImpl md({DateTimeAlignment? alignment, DateTimeLength? length}) =>
@@ -48,11 +48,11 @@
       DateFormatterX.mde(this, localeX, alignment?.toX, length?.toX);
 
   @override
-  FormatImpl y({
+  FormatterImpl y({
     DateTimeAlignment? alignment,
     DateTimeLength? length,
     YearStyle? yearStyle,
-  }) => DateFormatterUX.y(
+  }) => DateFormatterX.y(
     this,
     localeX,
     alignment?.toX,
diff --git a/pkgs/intl4x/lib/src/datetime_format/icu4x/time_formatter.dart b/pkgs/intl4x/lib/src/datetime_format/icu4x/time_formatter.dart
index 435c421..afb60b6 100644
--- a/pkgs/intl4x/lib/src/datetime_format/icu4x/time_formatter.dart
+++ b/pkgs/intl4x/lib/src/datetime_format/icu4x/time_formatter.dart
@@ -8,7 +8,7 @@
 import '../datetime_format_options.dart';
 import 'datetime_format_4x.dart';
 
-class TimeFormatterX extends FormatterImpl {
+class TimeFormatterX implements FormatterImpl {
   final icu.TimeFormatter formatter;
   final DateTimeFormatImpl impl;
   final icu.Locale localeX;
@@ -28,36 +28,24 @@
         alignment: alignment,
         length: length ?? icu.DateTimeLength.short,
         timePrecision: timePrecision,
-      ),
-      super(impl);
+      );
 
   @override
-  String formatInternal(DateTime datetime) {
+  String format(DateTime datetime) {
     final (_, time) = datetime.toX;
     return formatter.format(time);
   }
 
   @override
-  TimeFormatterZonedX withTimeZoneShort() => TimeFormatterZonedX.short(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLong() => TimeFormatterZonedX.long(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShortOffset() =>
-      TimeFormatterZonedX.shortOffset(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLongOffset() =>
-      TimeFormatterZonedX.longOffset(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneShortGeneric() =>
-      TimeFormatterZonedX.shortGeneric(this);
-
-  @override
-  ZonedDateTimeFormat withTimeZoneLongGeneric() =>
-      TimeFormatterZonedX.longGeneric(this);
+  ZonedDateTimeFormat withTimeZone(TimeZoneType timeZoneType) =>
+      switch (timeZoneType) {
+        TimeZoneType.short => TimeFormatterZonedX.short(this),
+        TimeZoneType.long => TimeFormatterZonedX.long(this),
+        TimeZoneType.shortOffset => TimeFormatterZonedX.shortOffset(this),
+        TimeZoneType.longOffset => TimeFormatterZonedX.longOffset(this),
+        TimeZoneType.shortGeneric => TimeFormatterZonedX.shortGeneric(this),
+        TimeZoneType.longGeneric => TimeFormatterZonedX.longGeneric(this),
+      };
 }
 
 class TimeFormatterZonedX extends FormatterZonedImpl {
diff --git a/pkgs/intl4x/test/datetime_format_conformance_test.dart b/pkgs/intl4x/test/datetime_format_conformance_test.dart
index 71b3c5e..40e6e2f 100644
--- a/pkgs/intl4x/test/datetime_format_conformance_test.dart
+++ b/pkgs/intl4x/test/datetime_format_conformance_test.dart
@@ -108,7 +108,7 @@
     >
   >
   options,
-  DateTimeFormat Function({
+  DateTimeFormattable Function({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,
diff --git a/pkgs/intl4x/test/datetime_format_test.dart b/pkgs/intl4x/test/datetime_format_test.dart
index 55ef2c3..db88b48 100644
--- a/pkgs/intl4x/test/datetime_format_test.dart
+++ b/pkgs/intl4x/test/datetime_format_test.dart
@@ -13,23 +13,12 @@
     testWithFormatting('DateTimeFormat dot shorthand', () {
       // Showcase the dot shorthand
       // ignore: omit_local_variable_types
-      final DateTimeFormat formatter = DateTimeFormat.year(
+      final DateTimeFormatUnzoneable formatter = DateTimeFormat.year(
         locale: Locale.parse('en-US'),
         yearStyle: YearStyle.full,
       );
       expect(formatter.format(dateTime), '2012');
     });
-
-    testWithFormatting(
-      'DateTimeFormat dot shorthand for ZonedDateTimeFormat',
-      () {
-        final DateTimeFormat formatter = DateTimeFormat.yearMonthDay(
-          locale: Locale.parse('en-US'),
-          yearStyle: YearStyle.full,
-        );
-        expect(formatter.format(dateTime), '12/20/2012');
-      },
-    );
   });
 
   group('Basic', () {
diff --git a/pkgs/intl4x/test/tools/regenerate_conformance_data.dart b/pkgs/intl4x/test/tools/regenerate_conformance_data.dart
index bf1b32e..a97d103 100644
--- a/pkgs/intl4x/test/tools/regenerate_conformance_data.dart
+++ b/pkgs/intl4x/test/tools/regenerate_conformance_data.dart
@@ -111,7 +111,7 @@
 
 void writeFor(
   String type,
-  DateTimeFormat Function({
+  DateTimeFormattable Function({
     Locale? locale,
     DateTimeAlignment? alignment,
     DateTimeLength? length,