Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Luxon weekdayShort giving null value for all dates | React native IOS real device only #1500

Closed
ashishmangukiya opened this issue Sep 6, 2023 · 10 comments

Comments

@ashishmangukiya
Copy link

Describe the bug
I am using luxon library to manage dates in my iOS application which is developed using react-native. In android it is working fine but in iOS real device it is giving null value from any date.

To Reproduce
Install latest luxon library in React native application.
Start iOS application in real device.
Use DateTime.now().weekdayShort and console it, It will give null value

Actual vs Expected behavior
Expected output should be like 'Mon', 'Tue' etc

  • OS: [iOS any version]
  • Luxon version [3.4.3]

Additional context
It is working fine in iOS simulator but in real device it is giving null value for all dates

@diesieben07
Copy link
Collaborator

React Native uses Hermes as its JavaScript engine, which unfortunately has many shortcomings in terms of its Intl.DateTimeFormat API implementation.
However, I am unable to reproduce this in Expo: https://snack.expo.dev/dVh0QsfdD (I do not have access to a physical iOS device). Included in the code is a test to do the same thing Luxon does using the Intl.DateTimeFormat API. Please test, if this code reports the correct value on your device. If not, this is a problem with your runtime, not with Luxon.

@ashishmangukiya
Copy link
Author

ashishmangukiya commented Sep 7, 2023

@diesieben07
The issue is only in iOS real device, Hermes is been used for Android only and not for iOS.
For iOS, JavascriptCore engine is been used.
I opened your expo link and run it on real iOS device. again same issue Link.

@diesieben07
Copy link
Collaborator

I will test on a real device later today and try to debug the problem.

@ashishmangukiya
Copy link
Author

Ok, If you need any help on debugging then let me know.

@diesieben07
Copy link
Collaborator

diesieben07 commented Sep 7, 2023

I have now confirmed that this indeed an issue with Hermes. Your statement that Hermes is only used on Android is incorrect. If I open the Expo link on a real iOS device, then global.HermesInternal is defined, meaning Hermes is in use.
Please verify again if you are really not using Hermes.

The following code demonstrates the problem:

const intl = new Intl.DateTimeFormat(undefined, { weekday: "short" });
console.log(intl.formatToParts());

In a correct implementation of DateTimeFormat (including in Safari on iOS) this produces the following:

[{ type: "weekday", "value": "Thu" }]

Hermes instead produces:

[{ type: "literal", "value": "Thu" }]

We might be able to add a work-around for this case, but I am reluctant to do so, because of potential negative effects on properly functioning engines.

@AndrewKirkovski
Copy link

Is there a known work around for this issue except disabling hermes for IOS?

@diesieben07
Copy link
Collaborator

Is there a known work around for this issue except disabling hermes for IOS?

You could install a Polyfill for the Intl API.

@krystiansliwa
Copy link

Is there a known work around for this issue except disabling hermes for IOS?

You could install a Polyfill for the Intl API.

I have the same issue. What polyfill you are referring to?

@diesieben07
Copy link
Collaborator

I have the same issue. What polyfill you are referring to?

https://formatjs.io/docs/polyfills/intl-datetimeformat/

@SerSerch
Copy link

SerSerch commented Mar 4, 2024

@diesieben07 I don't know why exactly this works on IOS

export function dateFormat(fmt, date) {
  try {
    const regex = /(\w)\1+|\w/g;
    const localDate = date || DateTime.local();

    return typeof fmt === 'string'
      ? fmt.replace(regex, function (match) {
          switch (match) {
            case 'EEE':
            case 'ccc':
              return localDate.toLocaleString({weekday: 'short'});
            case 'EEEE':
            case 'cccc':
              return localDate.toLocaleString({weekday: 'long'});
            case 'MMM':
            case 'LLL':
              return localDate.toLocaleString({month: 'short'});
            case 'MMMM':
            case 'LLLL':
              return localDate.toLocaleString({month: 'long'});

            // case 'DD':
            // case 'DDD':
            // case 'DDDD':
            // case 'ff':
            // case 'FF':
            //   return 'problem';

            default:
              return localDate.toFormat(match);
          }
        })
      : '';
  } catch (err) {
    console.log('ERROR[datetime] dateFormat', err);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants