fix: Fix timezone Date parsing for Hermes JS engine
When using the Hermes engine in the newer versions of React Native the timezone plugin doesn't work because there are a few places where the Date constructor is used to parse a en locale formatted date string and Hermes doesn't support that format of parsing (i.e. new Date('8/20/1999, 5:00:15 AM')). This issue results in the timezone plugin always returning GMT and UTC times when used in newer Expo and React Native apps. In order to work around this we can use dayjs itself to parse these dates instead of the native Date constructor. This PR allows dayjs to work in Expo and React Native with the timezone plugin.
Wow I've been needing this!
Can we get this merged before another dev loses their mind trying to debug this? ππ₯
Similar to https://github.com/iamkun/dayjs/pull/2227 but I think simpler because it just uses dayjs itself to do the parsing here. Either works though!
Also this Issue: https://github.com/facebook/hermes/issues/1519
π₯
Holy smokes he solved it !
oh boy I came to look for this exact issue, it's been driving me nuts for a day here. Hopefully this gets merged soon, thank you
looks like this should fix https://github.com/iamkun/dayjs/issues/1377.
@iamkun can you please take a look and merge it in?
if it fixes a tz support for React-Native with Hermes β it would be a huge win!
This is great!!!!! @milesingrams π
Coming here from @dlebedynskyi mention of this fix in https://github.com/iamkun/dayjs/issues/1377
Maybe this isnβt the right place to ask for help about this issue, but I thought Iβd share my experience in case anyone else is trying the same thing.
I tried using this branch as the reference for dayjs in my React Native project (with Hermes), and I wanted to share what I ran into when attempted to use this branch (with the fix). I cloned and built the repo using this branch, verified the fix was present in the code before building, and:
mkdir dayjs-tz-patch-milesingrams
cd dayjs-tz-patch-milesingrams
git clone --single-branch --branch fix-timezone-date-parsing-for-hermes-js-engine https://github.com/milesingrams/dayjs.git
cd dayjs
npm install
export NODE_OPTIONS=--openssl-legacy-provider
npm run build
npm pack
This created the file dayjs-0.0.0-development.tgz, which I installed in my React Native project like so:
npm install /absolute/path/to/dayjs-tz-patch-milesingrams/dayjs/dayjs-0.0.0-development.tgz
Despite this, the timezone behavior was still broken when running with Hermes β it was as if the fix wasnβt applied.
I was hoping that anyone here can confirm β if this is the correct way to apply and test a patch in a project? Just want to make sure I didnβt miss something!
This update does improve the timezone plugin using hermes although the test suite still shows some problems.
For reference I had to build a custom version of hermes to include support for Intl since that is not included by default (?). The support for Intl is currently a 'WIP'. It does look like dayjs only makes use of DateTimeFormat which appears to have good support in hermes.
set(HERMES_ENABLE_INTL OFF CACHE BOOL
"Enable JS Intl support (WIP)")
Then I used the the exodus-test module to run tests using hermes engine
npx exodus-test --jest --engine hermes:bundle test/plugin/timezone.test.js
npx exodus-test --jest --engine hermes:bundle test/plugin/timezone.test.js
hermes:bundle engine is experimental and may not work an expected
# test/plugin/timezone.test.js
β PASS Guess > return string
β PASS Parse > parse target time string
β PASS Parse > parse timestamp, js Date, Day.js object
β PASS Parse > parse and convert between timezones
β PASS Parse > preserve milliseconds
β PASS Convert > convert to target time
β PASS Convert > convert to target time
β PASS Convert > convert from time with timezone to target time
β PASS Convert > DST
β PASS Convert > format Z
β PASS DST, a time that never existed Spring Forward > 2012-03-11 01:59:59
β PASS DST, a time that never existed Spring Forward > 2012-03-11 02:00:00
β PASS DST, a time that never existed Spring Forward > 2012-03-11 02:59:59
β PASS DST, a time that never existed Spring Forward > 2012-03-11 03:00:00
β PASS DST, a time that never existed Fall Back > 2012-11-04 00:59:59
β PASS DST, a time that never existed Fall Back > 2012-11-04 00:59:59
β PASS DST, a time that never existed Fall Back > 2012-11-04 02:00:00
β PASS DST valueOf
β PASS set Default > default timezone
β PASS set Default > empty timezone means local timezone
β FAIL set Default > change default timezone
Error: expect(received).toBe(expected) // Object.is equality
Expected: "2014-06-01T12:00:00+09:00"
Received: "2014-06-01T12:09:00+08:48"
β FAIL set Default > override default timezone in proto.tz
Error: expect(received).toBe(expected) // Object.is equality
Expected: "2014-06-01T12:00:00+09:00"
Received: "2014-06-01T12:09:00+08:48"
β FAIL set Default > override default timezone in d.tz
Error: expect(received).toBe(expected) // Object.is equality
Expected: "2014-06-01T12:00:00+09:00"
Received: "2014-06-01T12:09:00+08:48"
β PASS keepLocalTime > keepLocalTime
β PASS Get offsetName > short
β FAIL Get offsetName > long
Error: expect(received).toBe(expected) // Object.is equality
Expected: "Eastern Standard Time"
Received: "Eastern"
β PASS CustomPraseFormat > normal
β PASS CustomPraseFormat > custom
β PASS startOf and endOf > corrects for timezone offset in startOf
β PASS startOf and endOf > corrects for timezone offset in endOf
β PASS startOf and endOf > preserves locality when tz is called
β PASS UTC timezone > TZ with UTC with Locale
β PASS UTC timezone > TZ with UTC
@konradjg Been following this thread closely and been looking at a lot of other threads and I think that nothing will get merged soon due to the fact that this is not a dayjs issue at all. It is mostly hermes issue and the main maintainer there have considered it super low priority https://github.com/facebook/hermes/issues/1519#issuecomment-2350062331 - For now I just went ahead with the ployfills suggested in https://github.com/iamkun/dayjs/issues/1377#issuecomment-2831492964 and I think there is nothing wrong with that. At least for me it is doing the job it needs to. I may try in the following days to switch the engine to JSC or v8 as there are speculations online that it may make the app faster due to date manipulation e.g. https://github.com/facebook/hermes/issues/930 or https://github.com/facebook/hermes/issues/495 or hermes_very_slow_compared_to_jsc_with_big_data