luxon icon indicating copy to clipboard operation
luxon copied to clipboard

Update documentation regarding Android Intl support

Open klfman opened this issue 3 years ago • 16 comments

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.

klfman avatar Feb 08 '21 13:02 klfman

Do we need to close that since Intl is now part of hermes 0.8.1 on react-native?

SudoPlz avatar Sep 03 '21 13:09 SudoPlz

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.

bviebahn avatar Sep 08 '21 08:09 bviebahn

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

SudoPlz avatar Sep 08 '21 11:09 SudoPlz

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.

bviebahn avatar Sep 08 '21 12:09 bviebahn

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?

bviebahn avatar Sep 08 '21 20:09 bviebahn

Just found this issue in the hermes repo which seems to be the cause of the problem: https://github.com/facebook/hermes/issues/572

bviebahn avatar Sep 09 '21 09:09 bviebahn

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.

chiubaka avatar Nov 12 '21 02:11 chiubaka

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

andreialecu avatar Nov 12 '21 09:11 andreialecu

Oh, amazing. You're a life saver @andreialecu!

chiubaka avatar Nov 12 '21 23:11 chiubaka

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!

vladyslavNiemtsev avatar Feb 10 '22 14:02 vladyslavNiemtsev

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 avatar Feb 10 '22 14:02 andreialecu

@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?

vladyslavNiemtsev avatar Feb 10 '22 14:02 vladyslavNiemtsev

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

bviebahn avatar Feb 10 '22 14:02 bviebahn

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 avatar Feb 10 '22 14:02 andreialecu

@andreialecu Got it. Thanks for clarifying.

So, basically you hold Hermes 'off' for IOS to use JSC?

vladyslavNiemtsev avatar Feb 10 '22 14:02 vladyslavNiemtsev

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?

hufftheweevil avatar Jul 21 '22 19:07 hufftheweevil