Closed ashishmangukiya closed 6 months ago
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.
@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.
I will test on a real device later today and try to debug the problem.
Ok, If you need any help on debugging then let me know.
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.
Is there a known work around for this issue except disabling hermes for IOS?
Is there a known work around for this issue except disabling hermes for IOS?
You could install a Polyfill for the Intl API.
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?
I have the same issue. What polyfill you are referring to?
@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);
}
}
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 givenull
valueActual vs Expected behavior Expected output should be like 'Mon', 'Tue' etc
Additional context It is working fine in iOS simulator but in real device it is giving
null
value for all dates