Repository: jama5262/jiffy

Issue:
Bring back some way to obtain a list of supported locale codes by Jiffy
**Is your feature request related to a problem? Please describe.**

Since `6.0.0`, there is currently no way (as far as I know) to obtain which locales are supported by Jiffy.
Prior to `6.0.0`, I've regularly used `Jiffy.getAllAvailableLocales()` to find and match the closest locale to the one currently chosen by the user. Some locale codes include or lack a region associated with the language. In a hypothetical scenario these regions (as well as the language) can be custom ones or not included in the locale code standards. Additionally, Jiffy does not support **all** languages and corresponding regions codes. My solution was to scan through available locales and match, in priority, a user's selected locale **exactly** to one supported by Jiffy. If not found, then match a language **without the region**. If not found, then match a language with a different region. If still not found, match a default locale that is definitely supported by both. It worked very well. Now, there is no functionality to do this anymore. In addition, Jiffy uses `en_US` as a default locale if it wasn't found through `setLocale` or other means which may not be desirable if it cannot be configured or at least checked for compatibility prior to calling `setLocale`.

**Describe the solution you'd like**

Possible simple solutions: 

- Rename field `_availableLocales` to `availableLocales` in `available_locales.dart` and make some method or field a part of `jiffy.dart` or otherwise, that acts as a wrapper to `availableLocales`, which could return just the keys of available locales:
  
  ```
  static final Iterable<String> keys = availableLocales.keys;
  ```
- Rename field `_availableLocales` to `availableLocales` in `available_locales.dart`, make `availableLocales` immutable, and include it in exports in `jiffy.dart`.
- Implement similar changes to at least detect if a specific locale tag is supported.

**Describe alternatives you've considered**

Currently, I have to resort to making my own list of supported Jiffy locales separately to which locales my app fundamentally supports, based on `available_locales.dart` and update it manually between Jiffy versions, which is not ideal.

**Additional context**

Not required.


Discussion: @deezee30 Hmmm, I would advise against relying solely on Jiffy's locales. In terms of design, it is better to maintain your own list of locales that you can provide to your users. This approach gives you complete control and avoids excessive dependence on Jiffy. 

By managing your own locales, you can customize the options to fit your specific needs, ensuring a more tailored and controlled experience for your users.

So in short, having your own list of supported locales is the best approach in my opinion

What do you think?
@jama5262 Completely agree with you. And that's what we are currently doing.

However, our own supported locales differ to Jiffy's. But when a user switches a locale within the app, we would like to configure Jiffy to change its locale too to keep it consistent. The issue lies in the fact that the chosen locale may not be supported by Jiffy. That's why we try to match the next closest locale based on what Jiffy **does** support.

Sorry for not being clear enough the first time.
Hmm, ok 👍 , I will add `getAllAvailableLocales()` function back to Jiffy, will update when it's fully released, won't be long
Thanks for all your great work :)

Fix patch:
diff --git a/doc/README.md b/doc/README.md
index cf24665f..a60a549d 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -661,3 +661,7 @@ Jiffy.now().yMMMMEEEEdjm; // 2019年10月19日星期六 下午7:28
 ```dart
 var localeCode = Jiffy.now().localeCode; // eu_us
 ```
+## Getting a list of supported locales
+```dart
+final supportLocales = Jiffy.getSupportedLocales(); // ['en_us', 'en', 'fr', ...]
+```
\ No newline at end of file
diff --git a/lib/src/jiffy.dart b/lib/src/jiffy.dart
index 0aca7873..1418767f 100644
--- a/lib/src/jiffy.dart
+++ b/lib/src/jiffy.dart
@@ -6,9 +6,9 @@ import './display.dart';
 import './enums/start_of_week.dart';
 import './enums/unit.dart';
 import './getter.dart';
-import './locale/available_locales.dart';
 import './locale/locale.dart';
 import './locale/locales/en_locale.dart';
+import './locale/supported_locales.dart' as supported_locales;
 import './manipulator.dart';
 import './parser.dart';
 import './query.dart';
@@ -218,8 +218,8 @@ class Jiffy {
   void _initializeLocale() {
     var systemLocale = Intl.getCurrentLocale();
 
-    if (isLocalAvailable(systemLocale)) {
-      _locale = getLocale(systemLocale);
+    if (supported_locales.isLocalSupported(systemLocale)) {
+      _locale = supported_locales.getLocale(systemLocale);
     } else {
       // The locale `systemLocale` is not supported by Jiffy, hence '
       // 'setting a default locale of `en_us`
@@ -254,7 +254,7 @@ class Jiffy {
   /// Throws a [JiffyException] if the [locale] provided is not supported in
   /// [Jiffy].
   static Future<void> setLocale(String locale) async {
-    if (isLocalAvailable(locale)) {
+    if (supported_locales.isLocalSupported(locale)) {
       Intl.defaultLocale = locale;
       await initializeDateFormatting();
     } else {
@@ -265,6 +265,22 @@ class Jiffy {
     }
   }
 
+  /// Retrieves a list of supported locales in Jiffy.
+  ///
+  /// This static method returns a list of supported locales by invoking the
+  /// `getSupportedLocales()` method from the `supported_locales` module.
+  ///
+  /// The returned list contains strings representing the supported locales.
+  ///
+  /// Example usage:
+  ///
+  /// ```dart
+  /// final supportLocales = Jiffy.getSupportedLocales();
+  /// print(supportLocales); // ['en_us', 'en', 'fr', ...]
+  /// ```
+  static List<String> getSupportedLocales() =>
+      supported_locales.getSupportedLocales();
+
   /// Returns a new [Jiffy] instance with the same date and time as the
   /// original instance.
   ///
diff --git a/lib/src/locale/available_locales.dart b/lib/src/locale/supported_locales.dart
similarity index 87%
rename from lib/src/locale/available_locales.dart
rename to lib/src/locale/supported_locales.dart
index 0c4cfcfc..b3f82ae0 100644
--- a/lib/src/locale/available_locales.dart
+++ b/lib/src/locale/supported_locales.dart
@@ -24,7 +24,7 @@ import 'locales/tr_locale.dart';
 import 'locales/zh_locale.dart';
 import 'locales/bn_locale.dart';
 
-Map<String, Locale> _availableLocales = {
+Map<String, Locale> _supportedLocales = {
   'en': EnLocale(),
   'en_us': EnUsLocale(),
   'en_sg': EnSgLocale(),
@@ -79,9 +79,13 @@ Map<String, Locale> _availableLocales = {
 };
 
 Locale getLocale(String locale) {
-  return _availableLocales[locale.toLowerCase()] ?? _availableLocales['en_us']!;
+  return _supportedLocales[locale.toLowerCase()] ?? _supportedLocales['en_us']!;
 }
 
-bool isLocalAvailable(String locale) {
-  return _availableLocales.containsKey(locale.toLowerCase());
+bool isLocalSupported(String locale) {
+  return _supportedLocales.containsKey(locale.toLowerCase());
+}
+
+List<String> getSupportedLocales() {
+  return _supportedLocales.keys.toList();
 }


Test patch:
diff --git a/test/src/jiffy_test.dart b/test/src/jiffy_test.dart
index 223008bc..28a90745 100644
--- a/test/src/jiffy_test.dart
+++ b/test/src/jiffy_test.dart
@@ -27,6 +27,8 @@ import 'package:jiffy/src/utils/jiffy_exception.dart';
 import 'package:test/expect.dart';
 import 'package:test/scaffolding.dart';
 
+import 'locale/supported_locales_test.dart';
+
 void main() {
   group('Test parsing and creating a Jiffy instance', () {
     test('Should successfully parse from string', () {
@@ -248,6 +250,22 @@ void main() {
       expect(actualLocaleCode, expectedLocaleCode);
     });
 
+    group('Test available locales', () {
+      test('Should successfully return a list of available locales', () {
+        // Setup
+        final expectedSupportedLocales = supportedLocales();
+
+        // Execute
+        final actualSupportedLocales = Jiffy.getSupportedLocales();
+
+        actualSupportedLocales.sort();
+        expectedSupportedLocales.sort();
+
+        // Verify
+        expect(actualSupportedLocales, expectedSupportedLocales);
+      });
+    });
+
     test('Should successfully get start of week', () async {
       // Setup
       await Jiffy.setLocale('ja');
diff --git a/test/src/locale/supported_locales_test.dart b/test/src/locale/supported_locales_test.dart
new file mode 100644
index 00000000..69115cde
--- /dev/null
+++ b/test/src/locale/supported_locales_test.dart
@@ -0,0 +1,77 @@
+import 'package:jiffy/src/locale/supported_locales.dart';
+import 'package:test/expect.dart';
+import 'package:test/scaffolding.dart';
+
+void main() {
+  group('Test available locales', () {
+    test('Should successfully return a list of available locales', () {
+      // Setup
+      final expectedSupportedLocales = supportedLocales();
+
+      // Execute
+      final actualSupportedLocales = getSupportedLocales();
+
+      actualSupportedLocales.sort();
+      expectedSupportedLocales.sort();
+
+      // Verify
+      expect(actualSupportedLocales, expectedSupportedLocales);
+    });
+  });
+}
+
+List<String> supportedLocales() {
+  return [
+    'en_us',
+    'en',
+    'en_sg',
+    'en_au',
+    'en_ca',
+    'en_gb',
+    'en_ie',
+    'en_il',
+    'en_nz',
+    'es',
+    'es_do',
+    'es_us',
+    'fr',
+    'fr_ch',
+    'fr_ca',
+    'zh',
+    'zh_cn',
+    'zh_hk',
+    'zh_tw',
+    'de',
+    'de_de',
+    'de_at',
+    'de_ch',
+    'it',
+    'it_ch',
+    'ar',
+    'ar_ly',
+    'ar_dz',
+    'ar_kw',
+    'ar_sa',
+    'ar_ma',
+    'ar_tn',
+    'az',
+    'id',
+    'ja',
+    'ko',
+    'ru',
+    'uk',
+    'hi',
+    'hu',
+    'hu_hu',
+    'pt',
+    'pt_br',
+    'pl',
+    'tr',
+    'sv',
+    'nb',
+    'fa',
+    'bn',
+    'nl',
+    'th'
+  ];
+}