虽然您可以只创建一个解析函数,而忽略使用内置日期格式化功能或其他日期操作库(您将了解到这些库也可能无法在 Android 上运行!),但让我们来说明您为什么使用 @ 987654324@ 适用于 iOS 而不是 Android,因为这是这个问题中更有趣的部分。
为什么我不能在 Android 上使用 Intl?
您的 React Native JS 代码在 javascript 引擎中执行,这在 iOS 和 Android 之间是不同的。
iOS - 使用 JavaScriptCore (JSC) 引擎,重要的是,这是 WebKit 使用的引擎,并且源自设备上 Safari 中的现有实现。
Android - 也使用 JSC,但是这不是来自操作系统提供的 Web 浏览器,而是其用于 JSC 引擎的无头版本的二进制文件作为 React Native 的 NPM 依赖项包含在内。
Hermes - 当然,iOS 和 Android 都可以设置为忽略默认值并使用 Hermes JS 引擎,在这方面它的行为与 Android 相同
Intl 是一个主要用于 UI 的规范,并在大多数现代浏览器中实现,包括 iOS Safari,这就是为什么作为 React Native 运行时的一部分执行的代码能够使用它的原因。
然而,作为一个无头 JS 引擎,Android 包含的 JSC 被剥离并缺少许多专注于 UI 的 API,因为无头 JS 引擎往往用于非 UI 目的,因此无需添加 UI 膨胀。因此它没有可用的Intl API。
当使用附加到 Android 模拟器或 Android 设备的 React Native 调试器时,这可能会特别令人困惑,因为这似乎适用于 Android!这是因为在使用调试器时,React Native 会将其 JS 运行时委托给调试器的运行时,因此实际上是在您计算机上的 Chrome 浏览器实例提供的 V8 引擎中运行您的 JS(这将有 Intl API 可用) .
那么如何在 Android 上使用缺少的国际化?
有几种方法可以做到这一点...
使用不同的 JSC 构建
您可以将 Android 配置为使用具有国际化功能的不同 JSC 版本
打开你的android/app/build.gradle,你会发现这个配置块
/**
* The preferred build flavor of JavaScriptCore.
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'
使用示例并替换 org.webkit:android-jsc-intl:+ 变体,或找到适合您需要的其他变体。
添加一个 polyfill
使用 NPM 上可用的 intl polyfill,您可以在代码中修补对 Intl API 的支持。这将始终在修补之前测试Intl API 的存在,因此也可以安全地包含在您的 iOS 代码中。
您也可以只配置您需要的语言环境包,这有助于减小您的应用程序的大小。
在您的应用入口文件中导入 polyfill 和语言环境数据将使其可在应用中的任何位置用作 Intl
npm install --save intl
// configure Intl polyfill
import 'intl';
import 'intl/locale-data/jsonp/en'; // other local data is available, import each locale that you need
由于 React Native JS 运行时的进一步限制,您可能还需要 disable regexp caching
// https://www.npmjs.com/package/intl#regexp-cache--restore
import IntlPolyfill from 'intl';
IntlPolyfill.__disableRegExpRestore();
爱马仕呢???
如果使用 Hermes,更改 JSC 风格将不起作用,因为 Hermes 将 JSC 替换为 JavaScript 运行时。然而,使用 polyfill 也适用于 Hermes 构建。
我为什么要解决这个问题?
除了像您的用例一样对日期操作有用之外,以任何形式修补 Intl API 在您的 React Native 应用程序中都是值得努力的,因为它还允许您使用国际化库的全部功能,例如as react-intl,它可以帮助你以声明的方式实现日期、时间、数字、货币、语言等的 i18n