Moment: in, in den USA lokal

Erstellt am 24. Nov. 2016  ·  42Kommentare  ·  Quelle: moment/moment

Nur eine Frage:

Warum gibt es keine "en", "en-US" Gebietsschemas?
Ich verstehe, dass sie als Standardwert verwendet wurden. Wenn Sie dies wünschen, müssen Sie zunächst kein Gebietsschema verwenden.
Stellen Sie sich jedoch vor, Sie haben die typische Kombination, bei der der Benutzer das Gebietsschema auswählen kann.
Und Sie rufen moment.locale () mit dem aktuellen Wert auf.
In der aktuellen Situation muss man den Fall en / en-US als Sonderfall behandeln, was mir etwas umständlich erscheint.

Vielen Dank für Ihre großartige Arbeit. Drücke weiter!

Hilfreichster Kommentar

@icambron Meine Umgebung ist eine React Native-Anwendung, die npm verwendet, um meine Abhängigkeiten zu steuern, und ich konnte den Fehler auch in minimalen Beispielanwendungen replizieren. Das Problem ist, dass in der Funktion loadLocale versucht wird, ('./ locale /' + name) anzufordern, wobei name en-US ist, und dass dies fehlschlägt. Wenn diese Anforderung in einem Release-Build fehlschlägt, stürzt die App mit einem Stack-Trace ab, wie folgt:

E/ReactNativeJS: Requiring unknown module "./locale/en-us".
E/AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
                                                                Process: com.myApp, PID: 30054
                                                                com.facebook.react.common.JavascriptException: Requiring unknown module "./locale/en-US"., stack:
                                                                o<strong i="7">@2</strong>:742
                                                                n<strong i="8">@2</strong>:426
                                                                i<strong i="9">@2</strong>:278
                                                                t<strong i="10">@2</strong>:210
                                                                Xe<strong i="11">@648</strong>:16702
                                                                nt<strong i="12">@648</strong>:17804
                                                                gt<strong i="13">@648</strong>:22583
                                                                yt<strong i="14">@648</strong>:22460
                                                                wt<strong i="15">@648</strong>:23200
                                                                c<strong i="16">@648</strong>:1112
                                                                parse<strong i="17">@645</strong>:1536
                                                                render<strong i="18">@643</strong>:2923
                                                                _renderValidatedComponentWithoutOwnerOrContext<strong i="19">@141</strong>:7295
                                                                _renderValidatedComponent<strong i="20">@141</strong>:7462
                                                                performInitialMount<strong i="21">@141</strong>:3012
                                                                mountComponent<strong i="22">@141</strong>:2056
                                                                mountComponent<strong i="23">@132</strong>:205
                                                                performInitialMount<strong i="24">@141</strong>:3162
                                                                mountComponent<strong i="25">@141</strong>:2056
                                                                mountComponent<strong i="26">@132</strong>:205
                                                                performInitialMount<strong i="27">@141</strong>:3162
                                                                mountComponent<strong i="28">@141</strong>:2056
                                                                mountComponent<strong i="29">@132</strong>:205

Wenn getLocale den Code durchblättert und feststellt, dass mein Schlüssel ('en-US') kein Array ist, fällt er in loadLocale, ohne jemals zu versuchen, mit 'en' übereinzustimmen, was nur passieren würde, wenn er in die Funktion selectLocale gehen würde.

BEARBEITEN: Nachdem Sie sich die Funktion "ChooseLocale" etwas genauer angesehen haben, wird immer noch versucht, "en-US" zu wählen und dann die Anforderung zu verfehlen, bevor Sie jemals "en" versuchen wenn dies ein Array wäre.
Seltsam ist auch die Tatsache, dass sich die Stelle, an der es bricht, in einem Versuch / Fang befindet und dennoch einen Absturz verursacht. Das ist eigentlich die wirklich verwirrende Sache hier.

BEARBEITEN 2: Beachten Sie, dass die Anforderung in einem Debug-Build (__DEV__) ordnungsgemäß fehlschlägt und dann auf die Verwendung von 'en' zurückzuführen ist. Ich bin mir nicht sicher, warum erfordern in __PROD__ so viel explosiver ist, aber es bricht hier definitiv im Moment.

BEARBEITEN 3: In den erforderlichen js-Dokumenten heißt es: "Wenn Sie die Abhängigkeiten nicht ausdrücken, werden wahrscheinlich Ladefehler angezeigt, da RequireJS Skripte asynchron und aus Geschwindigkeitsgründen nicht in der richtigen Reihenfolge lädt." Daher ist es unwahrscheinlich, dass der Versuch / Fang uns hier tatsächlich rettet, da Versuch / Fang nur bei synchronen Fehlern wirklich hilft.

Alle 42 Kommentare

Es gibt ein Gebietsschema en , das nur nicht in einer separaten Datei enthalten ist. Es wird von moment().locale() und moment.locale() sehr akzeptiert:

moment.locale('fr')
"fr"
moment().format("LLLL")
"vendredi 25 novembre 2016 03:39"
moment.locale('en')
"en"
moment().format("LLLL")
"Friday, November 25, 2016 3:39 AM"

en-US funktioniert auch, weil wir nach einer weniger spezifischen Übereinstimmung suchen und das Gebietsschema en US-Englisch ist:

moment.locale('en-GB')
"en-gb"
moment().format("LLLL")
"Friday, 25 November 2016 03:40"
moment.locale('en-US')
"en"
moment().format("LLLL")
"Friday, November 25, 2016 3:40 AM"

Ich kaufe es nicht; Betrachten Sie den Fall, in dem das Gebietsschema von der Umgebung erkannt wird und dann ein erforderlicher Dep-Pfad erstellt wird, um moment / locale / $ {detectLocale} zu laden. Wenn diese Variable "en" oder "en-us" ist, kann requirejs keine Datei laden (erhält eine 404). Wenn es als ‚de‘ erkannt wird, dann wird die Datei laden.

Der Locale Loader von @eigood Moment weiß, dass er bereits Englisch spricht, und versucht nicht, es aus einer externen Datei zu laden.

@icambron Ich glaube nicht, dass Sie richtig sind, wenn Sie den Baum hinuntergehen, wenn der Benutzer "en-US" als Gebietsschema eingibt. Tatsächlich debugge ich gerade und es bricht, weil Sie NICHT den Baum hinuntergehen.
Mein Anwendungsfall ist, dass ich moment.utc (myDate, myFormat, locale, true) aufrufe, wobei locale nur eine einzelne Zeichenfolge 'en-US' ist. Da diese Zeichenfolge nicht importiert werden kann (da keine Datei dafür vorhanden ist), es sich jedoch nicht um ein Array handelt, wird versucht, das Gebietsschema zu benötigen, und es werden dann Produktionsumgebungen unterbrochen.
Es scheint mir, dass das wirklich beste Verhalten darin besteht, en-US tatsächlich in die Liste der standardmäßig vorhandenen Gebietsschemas aufzunehmen (es ist momentan nicht vorhanden, nur en allein).

@steveccable Nun, es wird versucht, es zu laden, nur für den Fall, dass Sie eine spezifischere Lokalisierung hatten. Wenn es fehlschlägt, versucht es nur "en" und ist erfolgreich. Ich denke, die Trennung ist nur, dass es irgendwie für Sie kaputt geht, wenn Sie "en-US" nicht laden. Hier soll nichts explodieren; Es soll nur anmutig scheitern und zur nächsten Option übergehen. Sie müssen mir also mehr über Ihre Umgebung erzählen: Was läuft konkret falsch?

@icambron Meine Umgebung ist eine React Native-Anwendung, die npm verwendet, um meine Abhängigkeiten zu steuern, und ich konnte den Fehler auch in minimalen Beispielanwendungen replizieren. Das Problem ist, dass in der Funktion loadLocale versucht wird, ('./ locale /' + name) anzufordern, wobei name en-US ist, und dass dies fehlschlägt. Wenn diese Anforderung in einem Release-Build fehlschlägt, stürzt die App mit einem Stack-Trace ab, wie folgt:

E/ReactNativeJS: Requiring unknown module "./locale/en-us".
E/AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
                                                                Process: com.myApp, PID: 30054
                                                                com.facebook.react.common.JavascriptException: Requiring unknown module "./locale/en-US"., stack:
                                                                o<strong i="7">@2</strong>:742
                                                                n<strong i="8">@2</strong>:426
                                                                i<strong i="9">@2</strong>:278
                                                                t<strong i="10">@2</strong>:210
                                                                Xe<strong i="11">@648</strong>:16702
                                                                nt<strong i="12">@648</strong>:17804
                                                                gt<strong i="13">@648</strong>:22583
                                                                yt<strong i="14">@648</strong>:22460
                                                                wt<strong i="15">@648</strong>:23200
                                                                c<strong i="16">@648</strong>:1112
                                                                parse<strong i="17">@645</strong>:1536
                                                                render<strong i="18">@643</strong>:2923
                                                                _renderValidatedComponentWithoutOwnerOrContext<strong i="19">@141</strong>:7295
                                                                _renderValidatedComponent<strong i="20">@141</strong>:7462
                                                                performInitialMount<strong i="21">@141</strong>:3012
                                                                mountComponent<strong i="22">@141</strong>:2056
                                                                mountComponent<strong i="23">@132</strong>:205
                                                                performInitialMount<strong i="24">@141</strong>:3162
                                                                mountComponent<strong i="25">@141</strong>:2056
                                                                mountComponent<strong i="26">@132</strong>:205
                                                                performInitialMount<strong i="27">@141</strong>:3162
                                                                mountComponent<strong i="28">@141</strong>:2056
                                                                mountComponent<strong i="29">@132</strong>:205

Wenn getLocale den Code durchblättert und feststellt, dass mein Schlüssel ('en-US') kein Array ist, fällt er in loadLocale, ohne jemals zu versuchen, mit 'en' übereinzustimmen, was nur passieren würde, wenn er in die Funktion selectLocale gehen würde.

BEARBEITEN: Nachdem Sie sich die Funktion "ChooseLocale" etwas genauer angesehen haben, wird immer noch versucht, "en-US" zu wählen und dann die Anforderung zu verfehlen, bevor Sie jemals "en" versuchen wenn dies ein Array wäre.
Seltsam ist auch die Tatsache, dass sich die Stelle, an der es bricht, in einem Versuch / Fang befindet und dennoch einen Absturz verursacht. Das ist eigentlich die wirklich verwirrende Sache hier.

BEARBEITEN 2: Beachten Sie, dass die Anforderung in einem Debug-Build (__DEV__) ordnungsgemäß fehlschlägt und dann auf die Verwendung von 'en' zurückzuführen ist. Ich bin mir nicht sicher, warum erfordern in __PROD__ so viel explosiver ist, aber es bricht hier definitiv im Moment.

BEARBEITEN 3: In den erforderlichen js-Dokumenten heißt es: "Wenn Sie die Abhängigkeiten nicht ausdrücken, werden wahrscheinlich Ladefehler angezeigt, da RequireJS Skripte asynchron und aus Geschwindigkeitsgründen nicht in der richtigen Reihenfolge lädt." Daher ist es unwahrscheinlich, dass der Versuch / Fang uns hier tatsächlich rettet, da Versuch / Fang nur bei synchronen Fehlern wirklich hilft.

Nachdem ich es ein wenig durchgearbeitet habe, habe ich eine (weniger als ideale) Problemumgehung. Wenn mein Code versucht, ein Gebietsschema von 'en-US' zu übergeben, fange ich ihn ab und übergebe stattdessen ein Gebietsschema von 'en'. Andere Gebietsschemas dürfen unverändert durchlaufen werden.

Trotzdem halte ich es immer noch für problematisch, dass es weder en-US finden kann noch standardmäßig bereits vorhanden ist, und Sie können es nicht wie bei anderen Gebietsschemas spezifisch einschließen, um zu vermeiden, dass es nicht gefunden wird, wenn es tatsächlich aufgerufen wird auf.

@steveccable

Seltsam ist auch die Tatsache, dass sich die Stelle, an der es bricht, in einem Versuch / Fang befindet und dennoch einen Absturz verursacht. Das ist eigentlich die wirklich verwirrende Sache hier.

Richtig, das sage ich. Ich versuche zu verstehen, warum ein fehlgeschlagener Anruf katastrophal wäre. Ich würde nicht helfen, in Kenntnis von en-US zu codieren; In jedem anderen Fallback-Fall hätten wir immer noch einen ähnlichen Fehler. Das hat also nichts damit zu tun, dass en ein Sonderfall ist, sondern damit, dass der Fallback-Prozess in Ihrer Umgebung überhaupt nicht funktioniert.

Wenn Sie es durcharbeiten, scheint es, dass React Native nicht so fehlerhaft behandelt werden kann, wie wir es möchten. Sie haben Recht, dass es nichts damit zu tun hat, dass es sich um einen Sonderfall handelt, und der einzige Grund, warum es so schien, als wäre es ein Sonderfall, war, dass es keine Möglichkeit gab, das Scheitern der en-US-Anforderung zu verhindern (da wir es nicht direkt importieren können wie bei anderen Gebietsschemas). Wie in der späteren Bearbeitung erwähnt, funktioniert try / catch nicht, da es asynchron fehlschlägt.
Im Moment funktioniert die oben erwähnte Problemumgehung, nur Gebietsschemas von "en-US" zu bereinigen, für meine Zwecke.

Der Versuch / Fang funktioniert nicht, da er asynchron fehlschlägt

Oh, ich habe diese Bearbeitung verpasst. Das würde auch meine Vermutung sein.

@steveccable
Ich bin mir nicht sicher, ob Sie das Problem noch haben, aber genau die gleichen Abstürze beim Release-Build (obwohl mit dem französischen Gebietsschema) haben einen Arbeitstag für mich in Anspruch genommen 😢

E/ReactNativeJS: Requiring unknown module "./locale/fr".
(...)

Ich habe es gelöst mit:

import 'moment/locale/fr';

Vielleicht hilft es

Die Problemumgehung für die Bereinigung der Gebietsschemaeingabe ist in Ordnung, aber es ist wirklich beängstigend zu wissen, dass ein reaktionsfähiges natives require () an jedem Ort asynchron fehlschlagen kann und es keine Möglichkeit gibt, dies zu erfassen. Wenn ich ein nicht vorhandenes Gebietsschema oder eine zufällige Zeichenfolge (z. B. 'blah-Blah') sende, bedeutet dies, dass die App abstürzt und ich den Fehler nirgendwo behandeln kann. Also muss ich defensiv nachsehen, dass niemand diesen Fehler auslöst.

Nach Version 2.19.2 sind Probleme aufgetreten. Hier ist, was sich mit dieser Version geändert hat: https://github.com/moment/moment/compare/29afed6...328d51e Die Funktion updateLocale hat begonnen, loadLocale intern zu verwenden, was wiederum die Verwendung einer dynamischen Zeichenfolge https erfordert

Ich denke, dies schlägt bei der Reaktion auf native fehl, da Sie keine Dateien dynamisch über die Variable https://github.com/facebook/react-native/issues/6391 benötigen können

In meinem speziellen Fall importiere ich die en-gb-Datei, sodass sie zum Zeitpunkt des Aufrufs von moment.locale in locales[name] werden sollte. Ich bin mir nicht sicher, warum es durchfällt, um zu verlangen.

Ich bin mir nicht sicher, ob RN Priorität hat oder nicht, aber der Moment für RN wird für Monate unterbrochen.

Bei alledem scheint Facebook # 69 die produktivste Lösung zu sein, um alle zu entsperren. Ich werde mit @jeanlauliac sprechen und sehen, ob wir es am Montag zusammenführen können.

Nur um einige Hintergrundinformationen zu geben: Es gibt mehrere Gründe, warum wir dynamische Abhängigkeiten nicht unterstützen. Erstens bricht die statische Analyse ab, wenn Module dynamisch benötigt werden. Zweitens ist bei Verwendung dynamischer Anforderungen möglicherweise das von Ihnen gesuchte reale Modul nicht verfügbar. Dies kann zu schwerwiegenden Problemen in der Produktion führen, die Benutzer daran hindern würden, unsere Apps zu verwenden, z. B. könnten wir Facebook beschädigen. Wir hatten in der Vergangenheit solche Probleme und es macht keinen Spaß, damit umzugehen. Metro hat absichtlich eine Meinung, um zu verhindern, dass Menschen Dinge tun, die den Benutzern Schmerzen bereiten.

Schließlich verstehen wir, dass dieses Open-Source-Repo derzeit nicht in einem hervorragenden Zustand ist. Die gute Nachricht ist, dass noch nie mehr Leute bei FB an Metro gearbeitet haben, und wir haben eine Reihe wichtiger Änderungen vor uns, um Metro um eine Tonne besser zu machen, aber die schlechte Nachricht ist, dass es dringende Probleme gibt, die wir lösen müssen zu Open Source. Wir hoffen, dass dieses Repo in ein paar Monaten in einem viel besseren Zustand sein wird und dass es einfacher sein wird, dazu beizutragen. Geben Sie uns bitte etwas Zeit.

Für RN habe ich es im Release-Modus zum Laufen gebracht, indem ich zum ersten Teil des Gebietsschemas gewechselt habe (wahrscheinlich, was hinter den Bildschirmen passiert, wenn das Gebietsschema "xx-XX" nicht geladen werden kann). Im folgenden Snippet ist locale das Gebietsschema Ihres Geräts in der Form "xx-XX".

moment.locale(locale.indexOf("-") === -1 ? locale : locale.substr(0, locale.indexOf('-')))

Das ist komisches Verhalten.

https://stackoverflow.com/a/47260841/175825 Sie müssen ein bestimmtes Gebietsschema importieren, damit das Ökosystem sie nutzen kann.

Aufgrund dieser Magie kann ich keinen reaktionsgroßen Kalender dazu bringen, Daten wie mm/yy mit BigCalendar.momentLocalizer() anzuzeigen, da erwartet wird, dass das Gebietsschema geladen wird.

Ich könnte ein Problem mit dem React-Big-Kalender eröffnen, aber was ist mit der nächsten Bibliothek, auf die ich stoße und die ein bestimmtes Gebietsschema erwartet? Und der nächste?

Fügen Sie einfach das Gebietsschema en-us und verwenden Sie standardmäßig Magie.

Fügen Sie einfach das Gebietsschema en-us hinzu und verwenden Sie standardmäßig Magie.

Es wird das Problem nicht lösen, es gibt Sprachen wie Spanisch ( es-ES => es ), die automatisch zurückgreifen.

Für alle, die noch nach einer Lösung suchen, kann dies helfen, das Problem zu beheben (mit Ausnahme einiger Randfälle), aber das Grundproblem von RN, das beim Absturz require einen Absturz verursacht, wird nicht behoben:

import moment from 'moment/min/moment-with-locales.min.js';

// locale is the locale detected by react-native-device-info
// ts is the time
export const formatTime = (locale, ts) => {
const m = moment.utc(ts);
locale = chooseMomentLocale(locale);
m.locale(locale);
// other logic to determine whether to show the time as "9:43 pm", "yesterday", or "7/8/2018"

return formattedTime;
}

/**
 * Checks if the device locale is available in moment and returns the locale to be loaded
 * <strong i="7">@param</strong>  {string} locale locale to be checked
 * <strong i="8">@return</strong> {string}        locale to be loaded by moment
 */
const chooseMomentLocale = (locale) => {
  // make the locale lower case 
  // will fix crashes caused by "en-GB" (instead of "en-gb") not being found
  locale = locale.toLowerCase();  
  if (moment.locales().includes(locale)) { // check if the locale is included in the array returned by `locales()` which (in this case) tells us which locales moment will support
    return locale;
  } else if (moment.locales().includes(locale.substring(0, 2))) { 
    // check if the first two letters of the locale are included in the array returned by `locales()` which (in this case) tells us which locales moment will support
    // will fixes crashes caused by "en-US" not being found, as we'll tell moment to load "en" instead
    return locale.substring(0, 2);
  }
    // use "en-gb" (the default language and locale for my app) as a fallback if we can't find any other locale
    return 'en-gb'; 
};

Ich habe dieses Problem auch mit React Native erlebt und konnte es vermeiden, indem ich alle Gebietsschemas neben Moment einbezog, d. H.

import moment from 'moment'
import 'moment/min/locales'

(Alternativ wird auch moment/min/moment-with-locales bereitgestellt, das jedoch mit einigen unserer anderen Formatierer nicht kompatibel war.)

Dies ist ein super nerviges Problem.

Ist es nicht der springende Punkt bei Gebietsschemas, dass Sie nicht einmal darüber nachdenken müssen und sicher nicht "en-US" in Ihren Code fest codieren, nur weil SIE in den USA sind? Ich verstehe nicht, warum es nicht einfach genommen werden kann, wenn ein Gebietsschema von 'en-US' angefordert wird. Verursacht Menschen endlose Kopfschmerzen.

Ich habe dieses Problem vor einem Jahr gelöst, aber völlig vergessen, wie, dann muss ich von vorne anfangen. (Ich verwende eine Datumsauswahl in Angular und stelle mit diesem Fehler nur die minimale Implementierung in die Luft.)

Ich bekomme dies in Angular und versuche, die Datetime-Auswahl zu verwenden. Wenn ich die LOCALE auf so etwas wie en-GB setze, funktioniert es einwandfrei, aber ohne etwas anzugeben, erhalte ich dies. Ich wünschte, ich könnte herausfinden, wie ich das richtig beheben kann

image

Für RN habe ich es im Release-Modus zum Laufen gebracht, indem ich zum ersten Teil des Gebietsschemas gewechselt habe (wahrscheinlich, was hinter den Bildschirmen passiert, wenn das Gebietsschema "xx-XX" nicht geladen werden kann). Im folgenden Ausschnitt ist locale das Gebietsschema Ihres Geräts in der Form "xx-XX".

moment.locale(locale.indexOf("-") === -1 ? locale : locale.substr(0, locale.indexOf('-')))

Diese Lösung funktioniert für mich mit i18n und momentjs wie folgt:

// imports:
import moment from 'moment';
import i18n from './i18n';
import 'moment/locale/fr';

// constructor: 
moment.locale(i18n.locale.indexOf('-') === -1 ? i18n.locale : i18n.locale.substr(0, i18n.locale.indexOf('-')));

Ich experimentiere immer noch mit diesem Problem, indem ich die Version "moment" ausführe: "^ 2.22.2",
Irgendeine Korrektur in der letzten Version?

Ich werde mich auf dieses Thema einlassen.

  1. en-US als einige versteckte Standardform zu behandeln, die andere ist schlechtes Design.
  2. Ohne en-us-Gebietsschema weiß ich nicht, welche CDN-Version ich verwenden soll.
  3. Der Moment sieht beeindruckend aus, aber ich finde keine andere Lösung, da es ein schlechter Codegeruch ist, wenn en-US nicht mit anderen Gebietsschemas identisch ist.

Ich hatte auch diesen Fehler bei der Reaktion auf die Produktion, nachdem ich eine schöne Entwicklung erstellt hatte, die perfekt funktioniert.
Es wurde mit der vorgeschlagenen Lösung @adesmet und dem folgenden Refaktor gelöst:

function parseLocaleForMoment (language) {
  if (language.indexOf('-') === -1) return language
  else return language.substr(0, language.indexOf('-'))
}

Sieht so aus, als würde RN mit dem Moment so viel saugen, dass es einfacher ist, nur einen nativen Formatierer zu schreiben. Wahrscheinlich nur eine Codezeile, kugelsicher.

Habe es so repariert:

const subLocales = [
  'ar-tn',
  'ar-dz',
  'ar-kw',
  'ar-ma',
  'ar-sa',
  'ar-ly',
  'de-at',
  'de-ch',
  'en-sg',
  'en-au',
  'en-ca',
  'en-gb',
  'en-ie',
  'en-nz',
  'es-us',
  'es-do',
  'fr-ca',
  'fr-ch',
  'gom-latn',
  'hy-am',
  'pa-in',
  'pt-br',
  'sr-cyrl',
  'tl-ph',
  'tlh',
  'tet',
  'ms-my',
  'it-ch',
  'tzl',
  'tzm',
  'tzm-latn',
  'nl-be',
  'ug-cn',
  'uz-latn',
  'zh-cn',
  'zh-hk',
  'zh-tw'
];

let momentLocale = i18n.locale.toLowerCase();

if (!subLocales.includes(momentLocale)) {
  momentLocale = momentLocale.substring(0, 2);
}

moment.locale(momentLocale);

mit react native @tapz scheint zh : /

Dies kann daran liegen, dass zh und einige andere Gebietsschemas unterschiedlich formatiert sind, um zwischen vereinfacht und traditionell zu unterscheiden. Siehe https://gist.github.com/jacobbubu/1836273

@ rajivshah3 in der Tat hatte ich zh_Hant_HK was nicht mit der Tapz-Methode funktionierte. Ich verwende jetzt Ihre Methode, die der beste Weg zu sein scheint, um dieses Problem so reibungslos wie möglich zu lösen, danke für Ihren Beitrag 👍

Gleiches Problem, nur im RN-Produktionsmodus.

Das scheint für mich gut zu funktionieren.

import 'moment/locale/fr';
import 'moment/locale/es';
import 'moment/locale/de';
import 'moment/locale/en-gb';
import 'moment/locale/es-us';

const toMomentLocale = locale => {
  let momentLocale = locale;
  momentLocale = momentLocale.replace('_', '-').toLowerCase();
  momentLocale = ['en-gb', 'en-us'].includes(locale)
    ? momentLocale
    : momentLocale.split('-')[0];
  return momentLocale;
};

Solange die Daten importiert werden (oder en ) und den Fall respektieren, scheint es für uns gut zu funktionieren

Das ist wirklich lächerlich. Das Entfernen des Abschnitts -region des Sprachcodes ist keine Lösung.

1) Sie verlieren die regionale Spezifität des Gebietsschemas.
2) Schlimmer noch, diese Methode führt zu weiteren Abstürzen. Chinesisch ( zh ) zum Beispiel gibt es in den MomentJS-Gebietsschemas nicht einmal. Es sind nur zh-cn , zh-hk und zh-tw definiert. Wenn Sie also den obigen Code verwenden, um Regionen aus der Gebietsschema-Zeichenfolge zu entfernen, stürzt Ihre App auf den meisten chinesischen Geräten sofort ab. Nur knapp 800 Millionen Smartphone-Nutzer.

Meine vorübergehende (und absolut durchgeknallte) Problemumgehung für React Native lautet wie folgt:

const locale = 'zh-cn'; // or en-US etc
const languageCode = moment.locale(locale.indexOf("-") === -1 ? locale : locale.substr(0, locale.indexOf('-'))); // now 'zh', 'en' etc. Thanks <strong i="14">@adesmet</strong> 
let momentJsLocale;
switch(languageCode.toLowerCase()) {
  case 'zh':
    // No 'zh' locale exists in MomentJS. App will crash in production if used.
    momentJsLocale = 'zh-cn';
    break;
  case 'pa':
    momentJsLocale = 'pa-in';
    break;
  case 'hy':
    momentJsLocale = 'hy-am';
    break;
  default:
    momentJsLocale = languageCode.toLowerCase();
}
moment.locale(momentJsLocale);

@adammcarth Hallo, haben wir Neuigkeiten zu Moment-Locales, die für RN

Dies ist gerade bei einem Release-Build mit en-gb abgestürzt.

Ich habe ein ähnliches Problem wie; @simeyla .

Wenn ich Luxon zusammen mit Timepicker hinzufüge, tauchen Probleme auf und sie scheinen mit dem Gebietsschema "en-US" in Zusammenhang zu stehen.

@steveccable Nun, es wird versucht, es zu laden, nur für den Fall, dass Sie eine spezifischere Lokalisierung hatten. Wenn es fehlschlägt, versucht es nur "en" und ist erfolgreich. Ich denke, die Trennung ist nur, dass es irgendwie für Sie kaputt geht, wenn Sie "en-US" nicht laden. Hier soll nichts explodieren; Es soll nur anmutig scheitern und zur nächsten Option

Ein weiteres Problem bei der Behandlung von 'en-US' oder anderen gültigen Gebietsschemas mit Ausnahmen besteht darin, dass Sie beim Debuggen und Auffordern des Debuggers, Ausnahmen zu bremsen, wiederholt an diesem feststecken.

Es sollte einen besseren und einfacheren Weg geben, insbesondere für ein so großes Gebietsschema wie das "en-US".
Letztendlich sollten diese Gebietsschemas mit der Möglichkeit einer großen Zielgruppe / Nutzung vorab überprüft und behandelt werden, um die Geschwindigkeit zu berücksichtigen.

Ich habe die Lösung von @slorber geändert , um robuster zu sein. Dadurch wird ein eingehendes Gebietsschema (z. B. "zh_CN" in "zh-cn") neu formatiert und geprüft, ob es von Ihrer momentanen Installation unterstützt wird, indem Sie auf das Land zurückgreifen und dann auf en-us zurückgreifen.

const toMomentLocale = (locale) => {
  let newLocale = locale.replace('_', '-').toLowerCase();
  let tryLocales = [newLocale, newLocale.split('-')[0]];
  for (let i = 0; i < tryLocales.length; i++) {
    if (moment.locales().indexOf(tryLocales[i]) >= 0) return tryLocales[i];
  }
  return 'en-us';
};

// use it like this:
let m = moment();
m.locale(toMomentLocale('zh_CN')).format('LLL'); // "2019年12月11日上午9点33分" -- used "zh-cn"
moment.locale(toMomentLocale('ja_JP'));
moment().format('LLL') // 2019年12月11日 09:34 -- falls back to "ja"

Gleiches Problem, nur im IOS-Modus der RN-Produktion.

Das scheint für mich gut zu funktionieren.

Moment von "Moment" importieren;
'moment / locale / es' importieren;

Ich habe einige Zeit damit verbracht, dies zu debuggen. Vielen Dank an

Dies ist immer noch ein Problem 😢

Hallo Leute,

Ich habe ein kleines Paket für Sie erstellt -> https://github.com/tonix-tuft/moment-utl

npm install --save moment moment-utl

Sie können Folgendes verwenden, um alle unterstützten aktuellen Gebietsschemas zu ermitteln, ohne sie im Voraus laden zu müssen:

import { allSupportedLocales, allSupportedLocalesMap } from "moment-utl";

const locales = allSupportedLocales(); // As an array: ["af", "ar", "ar-dz", "ar-kw", "ar-ly", "ar-ma", "ar-sa", "ar-tn", "az", "be", "bg", ...,  "en", ..., "zh-tw"]

const localesMap = allSupportedLocalesMap(); // As an object: { "af": 1, "ar": 2, "ar-dz": 3, "ar-kw": 4, "ar-ly": 5, "ar-ma": 6, "ar-sa": 7, "ar-tn": 8, "az": 9, "be": 10, ..., "en": 27, "zh-tw": 128 };

moment-utl Peer hängt von moment , aber es bündelt alle moment Gebietsschemas
Nehmen Sie sie aus dem Verzeichnis moment/locale während Sie ein moment dev-Abhängigkeitspaket erstellen.

Da moment eine Peer-Abhängigkeit ist, sollten Sie bei Verwendung von ES6 sicherstellen, dass sowohl allSupportedLocales als auch allSupportedLocalesMap aktuelle Gebietsschemas mit moment Version, die Sie zusammen mit moment-utl in Ihrem Projekt installiert haben (z. B. wenn moment eines Tages ein neues Gebietsschema hinzufügt, sollte dies Sie abdecken), können Sie diese Gebietsschemas auch mit dem neu generieren moment-utl-locales Skript bereitgestellt von moment-utl .

Sie können es mit dem Befehl npx :

npm install -g npx    # Install npx if you don't have it yet
npx moment-utl-locales    # Run this command from your project's root folder

Wenn Sie dieses Skript verwenden, stellen Sie sicher, dass Sie es ausführen, bevor Sie Ihren Code mit Rollup oder Webpack bündeln (je nachdem, was Sie verwenden), damit ein aktuelles Gebietsschema-Array und -Objekt generiert wird, bevor Ihr Bundler auf sie stößt und sie hinzufügt dein letztes Bündel.

Ich hoffe das hilft!

Als Antwort auf @adammcarth überprüfen Sie bitte meine Antwort hier: https://github.com/tonix-tuft/moment-utl/issues/1#issuecomment -616088826

Dieses Problem hat die Leute bei Odoo heimgesucht und die vorgeschlagene Lösung bestand darin, die en-us-Datei manuell zu erstellen. Seufzer.

Was ich nicht verstehe, ist, warum Moment versucht, die en-us-Datei zu laden, wenn der Loader, wie oben erwähnt, wissen sollte, dass er bereits "en" hat, und es nicht dynamisch importieren sollte.

Auf jeden Fall ist es immer noch ein Albtraum für RN-Benutzer. Das Schlimmste ist, dass das Problem nur bei Produktions-Builds auftritt.

Eine versteckte Standardeinstellung ist ein Paket von Überraschungen ...

image

Dieses Problem hat die Leute bei Odoo heimgesucht und die vorgeschlagene Lösung bestand darin, die en-us-Datei manuell zu erstellen. Seufzer.

Was ich nicht verstehe, ist, warum Moment versucht, die en-us-Datei zu laden, wenn der Loader, wie oben erwähnt, wissen sollte, dass er bereits "en" hat, und es nicht dynamisch importieren sollte.

Auf jeden Fall ist es immer noch ein Albtraum für RN-Benutzer. Das Schlimmste ist, dass das Problem nur bei Produktions-Builds auftritt.

Eine versteckte Standardeinstellung ist ein Paket von Überraschungen ...

image

Ich werde 👎 dafür bekommen, aber meine Lösung bestand darin, moment gegen dayjs auszutauschen. Da sie dieselbe Funktions- / API-Benennung haben, war es für mich so einfach wie ein find all + replace all .

Ich teile nur mit, was ich für Leute getan habe, die dies in Betracht ziehen möchten.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen