luxon
luxon copied to clipboard
Update documentation regarding Android Intl support
Tested with: react-native: 0.63.3
The docs about react-native support (https://moment.github.io/luxon/docs/manual/matrix.html bottom of page) suggest to use jsc-android-buildscripts to fix missing Intl support on Android.
Using the suggested solution I could not achieve Intl support on Android (on iOS however it worked like a charm from the beginning).
Also, the suggested repo jsc-android-buildscripts does not seem to be regularly maintained and not working at the moment.
Googling around I found this solution that worked for me (without using jsc-android-buildscripts at all):
In android/app/build.gradle change the line
def jscFlavor = 'org.webkit:android-jsc:+'
to
def jscFlavor = 'org.webkit:android-jsc-intl:+'
See: https://stackoverflow.com/questions/61408101/how-to-have-luxons-intl-api-working-in-react-native
I would suggest testing this and considering putting it into the official Luxon docs in place of the jsc-android-buildscripts fix.
Do we need to close that since Intl is now part of hermes 0.8.1 on react-native?
I just created a new react-native project using npx react-native init AwesomeProject
. I added luxon, enabled hermes, and checked that I'm using 0.8.1. However I can't get luxon to work. DateTime.local({ zone: "Europe/Berlin" })
returns null
. For some reason it works when I enable Debug. Any help appreciated.
Are you on iOS or Android? Also are you sure you're using hermes ?
I was wrong, it looks like Intl, was implemented on Android hermes only, so let's keep it open until it's also working for iOS hermes.
For now I'm using
import { Platform } from 'react-native';
if (Platform.OS === 'ios') {
// Polyfills required to use Intl with Hermes engine
require('@formatjs/intl-getcanonicallocales/polyfill').default;
require('@formatjs/intl-locale/polyfill').default;
require('@formatjs/intl-pluralrules/polyfill').default;
require('@formatjs/intl-pluralrules/locale-data/en').default;
require('@formatjs/intl-numberformat/polyfill').default;
require('@formatjs/intl-numberformat/locale-data/en').default;
require('@formatjs/intl-datetimeformat/polyfill').default;
require('@formatjs/intl-datetimeformat/locale-data/en').default; // locale-data for en
require('@formatjs/intl-datetimeformat/add-all-tz').default; // Add ALL tz data
}
on iOS.
https://github.com/facebook/hermes/issues/23#issuecomment-912528102
I'm on Android and hermes is enabled and I checked that it's version 0.8.1. It works fine on iOS with hermes disabled. For now I'm using the formatjs polyfills, but I had hoped I didn't need them if I just upgraded react-native.
If someone wants to reproduce this I would appreciate it. What I did is simple:
- npx react-native init LuxonHermesIntl
- yarn add luxon
- enable hermes in app/build.gradle
- check DateTime.local({zone: 'America/New_York'}).isValid
- yarn android
DateTime.local({zone: 'America/New_York'}).isValid
is false, except if Debug is enabled.
I created a repo if you want to check it out: https://github.com/bviebahn/luxon-hermes-android-bug
Or am I misunderstanding something? Shouldn't this work without polyfills with hermes 0.8.1?
Just found this issue in the hermes repo which seems to be the cause of the problem: https://github.com/facebook/hermes/issues/572
Semi-related to this thread: I'm also using Luxon with React Native and Hermes. I am seeing this timezone invalid issue, unfortunately. It is solvable by using the @formatjs polyfills for Intl support (which is currently the only way to get Intl support on iOS with Hermes), but for whatever reason I get intolerably slow performance out of Luxon on Android when using those polyfills.
I don't really understand why, as it works just fine on iOS. On Android, though, my app becomes completely unusable with the @formatjs polyfills.
I don't really understand why, as it works just fine on iOS. On Android, though, my app becomes completely unusable with the @formatjs polyfills.
The formatjs polyfills have a huge performance problem because of an issue in the ECMA spec.
See here for a patch that negates the performance problem: https://github.com/formatjs/formatjs/pull/2827 (which didn't get merged).
There's an entire saga in a bunch of threads, but TLDR, you can apply this patch for a huge Android performance boost: https://github.com/andreialecu/formatjs-datetimeformat-perf/issues/1#issuecomment-964148112
Oh, amazing. You're a life saver @andreialecu!
Hey guys! @chiubaka @andreialecu @bviebahn Could you please confirm that it doesn't work without polyfills? It seems like here: https://github.com/facebook/hermes/issues/572#issuecomment-966939442
@andreialecu confirmed that needed code changes was merged into main repo and issue should be resolved.
Thanks!
I'm currently no longer using the polyfills.
Everything works without polyfills as per Hermes engine 0.10 and later. However, Hermes 0.10 is not part of a stable React Native release yet. I'm using yarn resolutions in package.json
to enforce this version:
"resolutions": {
"hermes-engine": "0.10.0"
}
@andreialecu Thanks for your update!
Do you mean that 0.10 Hermes supports Intl on IOS? Could you please give me a link to change log about it?
And could you confirm that everything is okay with using yarn resolutions approach?
It does work without polyfills starting with hermes version 0.10. For anyone coming across this keep in mind that there are still differences between android versions. I ended up not using hermes for now, in order to keep supporting Android 5 and 6. For more information have a look here: https://hermesengine.dev/docs/intl#limitations-across-android-sdks
edit: @vladyslavNiemtsev I used hermes 0.10 with yarn resolutions without any problems
Do you mean that 0.10 Hermes supports Intl on IOS?
Afaik Hermes does not support Intl on iOS yet. This thread is about Android, not iOS.
I'm personally using the default (JSC) on iOS, which doesn't need polyfills.
@andreialecu Got it. Thanks for clarifying.
So, basically you hold Hermes 'off' for IOS to use JSC?
Does anyone know how to get timezones to work in Android with a managed Expo project not using Hermes?
I am trying to use Settings.defaultZone = "America/New_York"
and all of my DateTimes become invalid.
I have attempted to use the intl
polyfill and also @formatjs/intl-datetimeformat
, with no luck on both of those.
It doesn't appear I can use JSC because there is no .gradle file when managed.
Any other suggestions?