iamkun / dayjs

⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API
https://day.js.org
MIT License
46.53k stars 2.28k forks source link

The timezone plugin is not compatible with React Native Hermes engine #1377

Open dortamiguel opened 3 years ago

dortamiguel commented 3 years ago

The timezone plugin throws a timezone RangeError error when calling .tz because React Native Hermes engine doesn't has support for Intl timezones and toLocaleString

This two lines are the ones that are throwing the error

https://github.com/iamkun/dayjs/blob/dev/src/plugin/timezone/index.js#L20

https://github.com/iamkun/dayjs/blob/dev/src/plugin/timezone/index.js#L98

Could be posible to update the plugin to not depend on Intl and toLocaleString('en-US', { timeZone: timezone }) ?

sohcah commented 3 years ago

I've been facing the same issue today.

With the formatjs polyfill that's recommended, I've got it partially working: dayjs.tz("2013-11-18 11:55", "America/Toronto") returns correctly with "2013-11-18T16:55:00.000Z"

However, it's not fully working: dayjs("2013-11-18 11:55").tz("America/Toronto") returns null

So, with a polyfill I'm able to get Parsing in Zone to work, but not Converting to Zone.

dortamiguel commented 3 years ago

@sohcah what polyfill setup are you using? I tried to use formatjs but I didn't managed to make it work

sohcah commented 3 years ago

@ellipticaldoor I created an empty polyfill.ts file, as the polyfill isn't required on iOS or Web, and created a polyfill.android.ts file which contains the following: https://gist.github.com/sohcah/c223886c3e40a7b9c0283cd0213e2a54 I've got a few console logs in there to test Converting and Parsing, giving me this output: image

Then I'm just putting import './polyfill.ts'; in my App.tsx file.

sohcah commented 3 years ago

My converting issue seems similar to #1356... so possibly related?

sohcah commented 3 years ago

Looks like Date.toLocaleString() works differently with the Polyfill. Running new Date().toLocaleString("en-US", { timeZone: "America/Toronto" }) in a browser returns "2/9/2021, 9:03:52 AM", whilst with the polyfill it returns 2/9/2021.

sohcah commented 3 years ago
// @ts-ignore
Date.prototype._toLocaleString = Date.prototype.toLocaleString;
// @ts-ignore
Date.prototype.toLocaleString = function (a, b) {
  if (b && Object.keys(b).length === 1 && "timeZone" in b && a === "en-US") {
    return Intl.DateTimeFormat("en-us", {
      year: "numeric",
      month: "2-digit",
      day: "2-digit",
      hour: "2-digit",
      minute: "2-digit",
      second: "2-digit",
      hour12: false,
      timeZone: b.timeZone,
    })
      .format(this)
      .replace(/(\d{2})\/(\d{2})\/(\d{4}),/g, "$3-$1-$2");
  }
  // @ts-ignore
  return this._toLocaleString(a, b);
};

I've ended up, at least temporarily, using this patch in my polyfill.android.ts (plus all the formatjs stuff from before). It's absolutely not perfect... and really not a great solution, but seems to sort the issue for me.

dlebedynskyi commented 3 years ago

Had run into same issue as @sohcah. Any update as official fix would be appreciated. Polyfills claim spec compliance https://formatjs.io/docs/polyfills/intl-datetimeformat/#default-timezone

I had to patch dayjs to isolate one call with ^^ workaround

troZee commented 3 years ago

Had run into same issue as @sohcah. Any update as official fix would be appreciated. Polyfills claim spec compliance https://formatjs.io/docs/polyfills/intl-datetimeformat/#default-timezone

I had to patch dayjs to isolate one call with ^^ workaround

Could you provide a code snippet ?

devinjameson commented 3 years ago

It's possible this might solve the problem on Android. In app build.gradle:

/**
 * The preferred build flavor of JavaScriptCore.
 *
 * For example, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US.  Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc-intl:+'
dlebedynskyi commented 3 years ago

@troZee

create gist with patch we are using now https://gist.github.com/dlebedynskyi/81ff281b0db6aa69cdb360a1b609fb8a

this is essentially your suggested change, but as patch

+                // HACK https://github.com/iamkun/dayjs/issues/1377
+                i = Intl.DateTimeFormat('en-us', {
+                    year: 'numeric',
+                    month: '2-digit',
+                    day: '2-digit',
+                    hour: '2-digit',
+                    minute: '2-digit',
+                    second: '2-digit',
+                    hour12: false,
+                    timeZone: t,
+                })

@devinjameson

It's possible this might solve the problem on Android. In app build.gradle:

We are trying to avoid this exactly. There are bugs in current JSC used in RN related to DST (in Brazil for example). You also need to use https://formatjs.io/docs/polyfills for Hermes (RN 0.64) Last adding JSC increases your apk size by >3mb

Rc85 commented 3 years ago

@troZee

create gist with patch we are using now https://gist.github.com/dlebedynskyi/81ff281b0db6aa69cdb360a1b609fb8a

this is essentially your suggested change, but as patch

+                // HACK https://github.com/iamkun/dayjs/issues/1377
+                i = Intl.DateTimeFormat('en-us', {
+                    year: 'numeric',
+                    month: '2-digit',
+                    day: '2-digit',
+                    hour: '2-digit',
+                    minute: '2-digit',
+                    second: '2-digit',
+                    hour12: false,
+                    timeZone: t,
+                })

@devinjameson

It's possible this might solve the problem on Android. In app build.gradle:

We are trying to avoid this exactly. There are bugs in current JSC used in RN related to DST (in Brazil for example). You also need to use https://formatjs.io/docs/polyfills for Hermes (RN 0.64) Last adding JSC increases your apk size by >3mb

Patched it and now I'm getting this error.

ReferenceError: Property 'Intl' doesn't exist
dlebedynskyi commented 3 years ago

Patched it and now I'm getting this error.

you are missing Intl library, probably on React Native Android - make sure you have JSC with Intl flavor, or latest Hermes with Intl, or add polyfill.

HenriqueeLoopes commented 3 years ago

@dlebedynskyi Intl has been added in the latest version(0.8.1) of Hermes.

DeveloperTheExplorer commented 2 years ago

It's possible this might solve the problem on Android. In app build.gradle:

/**
 * The preferred build flavor of JavaScriptCore.
 *
 * For example, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US.  Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc-intl:+'

You are a life saver <3

mattijsf commented 2 years ago

@dlebedynskyi Intl has been added in the latest version(0.8.1) of Hermes.

But it doesn't come with timezone conversion support. When using Hermes on iOS, Intl is not available entirely.

mattijsf commented 2 years ago

The above patch causes midnight dates to be formatted as 2010-01-01 24:00:00 after applying .startOf("day") (see here) once fed into the Date constructor by the .tz implementation (see here).

24:00 marks the end of the day, leading the Date constructor to parse it as Jan 02 2010 00:00:00 GMT+0100. By replacing hour12: false with hourCycle: "h23" in the patch above the correct date is formatted / converted when using .startOf("day") in combination with timezones.

Before:

  const originalDay = dayjs("2010-01-01T00:00:00Z").tz("UTC")
  const startOfDay = originalDay.startOf("day")
  console.log(startOfDay.valueOf() === originalDay.valueOf()) // false using above patch

After:

  const originalDay = dayjs("2010-01-01T00:00:00Z").tz("UTC")
  const startOfDay = originalDay.startOf("day")
  console.log(startOfDay.valueOf() === originalDay.valueOf()) // true, using above patch with hourCycle: "h23" instead of hour12: false
santhoshvai commented 2 years ago

The above patch causes midnight dates to be formatted as 2010-01-01 24:00:00 after applying .startOf("day") (see here) once fed into the Date constructor by the .tz implementation (see here).

24:00 marks the end of the day, leading the Date constructor to parse it as Jan 02 2010 00:00:00 GMT+0100. By replacing hour12: false with hourCycle: "h23" in the patch above the correct date is formatted / converted when using .startOf("day") in combination with timezones.

Before:

  const originalDay = dayjs("2010-01-01T00:00:00Z").tz("UTC")
  const startOfDay = originalDay.startOf("day")
  console.log(startOfDay.valueOf() === originalDay.valueOf()) // false using above patch

After:

  const originalDay = dayjs("2010-01-01T00:00:00Z").tz("UTC")
  const startOfDay = originalDay.startOf("day")
  console.log(startOfDay.valueOf() === originalDay.valueOf()) // true, using above patch with hourCycle: "h23" instead of hour12: false

Great find!

anggihnurh commented 2 years ago

It's possible this might solve the problem on Android. In app build.gradle:

/**
 * The preferred build flavor of JavaScriptCore.
 *
 * For example, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US.  Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc-intl:+'

I have enable this line, but always getting error timeZone is not supported

Aryk commented 2 years ago

@anggihnurh Im also still getting that error... did you figure it out?

dorthwein commented 2 years ago

There may still be some hair on this after reading through everyones comments, but here is a stitched together polyfill implementation to include in your top index.js file to get things working. Confirmed on iOS - I have not tried android yet.

Its important to note, the order you import the polyfills matters!!

Install things

yarn add @formatjs/intl-datetimeformat
yarn add @formatjs/intl-displaynames
yarn add @formatjs/intl-getcanonicallocales
yarn add @formatjs/intl-listformat
yarn add @formatjs/intl-locale
yarn add @formatjs/intl-numberformat
yarn add @formatjs/intl-pluralrules
yarn add @formatjs/intl-relativetimeformat

Add to your entry index.js file

import '@formatjs/intl-getcanonicallocales/polyfill';
import '@formatjs/intl-locale/polyfill';

import '@formatjs/intl-displaynames/polyfill';
import '@formatjs/intl-displaynames/locale-data/en'; // locale-data for en

import '@formatjs/intl-listformat/polyfill';
import '@formatjs/intl-listformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-pluralrules/polyfill';
import '@formatjs/intl-pluralrules/locale-data/en'; // locale-data for en

import '@formatjs/intl-numberformat/polyfill';
import '@formatjs/intl-numberformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-relativetimeformat/polyfill';
import '@formatjs/intl-relativetimeformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-datetimeformat/polyfill';
import '@formatjs/intl-datetimeformat/locale-data/en'; // locale-data for en
import '@formatjs/intl-datetimeformat/add-all-tz'; // Add ALL tz data

// @ts-ignore
Date.prototype._toLocaleString = Date.prototype.toLocaleString;
Date.prototype.toLocaleString = function (a, b) {
  if (b && Object.keys(b).length === 1 && 'timeZone' in b && a === 'en-US') {
    return Intl.DateTimeFormat('en-us', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false,
      timeZone: b.timeZone,
    })
      .format(this)
      .replace(/(\d{2})\/(\d{2})\/(\d{4}),/g, '$3-$1-$2');
  }
  // @ts-ignore
  return this._toLocaleString(a, b);
};

This is just a bump/summary of the folks above - they deserve the thank you if it works for you!

VictorPulzz commented 1 year ago

There may still be some hair on this after reading through everyones comments, but here is a stitched together polyfill implementation to include in your top index.js file to get things working. Confirmed on iOS - I have not tried android yet.

Its important to note, the order you import the polyfills matters!!

Install things

yarn add @formatjs/intl-datetimeformat
yarn add @formatjs/intl-displaynames
yarn add @formatjs/intl-getcanonicallocales
yarn add @formatjs/intl-listformat
yarn add @formatjs/intl-locale
yarn add @formatjs/intl-numberformat
yarn add @formatjs/intl-pluralrules
yarn add @formatjs/intl-relativetimeformat

Add to your entry index.js file

import '@formatjs/intl-getcanonicallocales/polyfill';
import '@formatjs/intl-locale/polyfill';

import '@formatjs/intl-displaynames/polyfill';
import '@formatjs/intl-displaynames/locale-data/en'; // locale-data for en

import '@formatjs/intl-listformat/polyfill';
import '@formatjs/intl-listformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-pluralrules/polyfill';
import '@formatjs/intl-pluralrules/locale-data/en'; // locale-data for en

import '@formatjs/intl-numberformat/polyfill';
import '@formatjs/intl-numberformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-relativetimeformat/polyfill';
import '@formatjs/intl-relativetimeformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-datetimeformat/polyfill';
import '@formatjs/intl-datetimeformat/locale-data/en'; // locale-data for en
import '@formatjs/intl-datetimeformat/add-all-tz'; // Add ALL tz data

// @ts-ignore
Date.prototype._toLocaleString = Date.prototype.toLocaleString;
Date.prototype.toLocaleString = function (a, b) {
  if (b && Object.keys(b).length === 1 && 'timeZone' in b && a === 'en-US') {
    return Intl.DateTimeFormat('en-us', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false,
      timeZone: b.timeZone,
    })
      .format(this)
      .replace(/(\d{2})\/(\d{2})\/(\d{4}),/g, '$3-$1-$2');
  }
  // @ts-ignore
  return this._toLocaleString(a, b);
};

This is just a bump/summary of the folks above - they deserve the thank you if it works for you!

Unfortunately on android when I call dayjs.tz.guess() return 'UTC' ...

Does anyone know what the problem is?

ospfranco commented 1 year ago

Heyo, I'm on RN 0.70.1 and facing issues with timezones on iOS (haven't tested Android yet).

I would like to get the timezone in relative GMT format, I've done the following:

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(advancedFormat);

dayjs.tz.setDefault(RNLocalize.getTimeZone()); // Sets timezone to Europe/Berlin

dayjs().format('z') => prints 'GMT' expect 'GMT +2'

I've tried adding the polyfills and the code posted by @dorthwein but when I start the app I get the following error:

simulator_screenshot_61FC24CB-1CED-48E3-9F93-A3F8F3C0AB8B

Have any of you got timezone support working on the latest RN versions?

ospfranco commented 1 year ago

There may still be some hair on this after reading through everyones comments, but here is a stitched together polyfill implementation to include in your top index.js file to get things working. Confirmed on iOS - I have not tried android yet. Its important to note, the order you import the polyfills matters!! Install things

yarn add @formatjs/intl-datetimeformat
yarn add @formatjs/intl-displaynames
yarn add @formatjs/intl-getcanonicallocales
yarn add @formatjs/intl-listformat
yarn add @formatjs/intl-locale
yarn add @formatjs/intl-numberformat
yarn add @formatjs/intl-pluralrules
yarn add @formatjs/intl-relativetimeformat

Add to your entry index.js file

import '@formatjs/intl-getcanonicallocales/polyfill';
import '@formatjs/intl-locale/polyfill';

import '@formatjs/intl-displaynames/polyfill';
import '@formatjs/intl-displaynames/locale-data/en'; // locale-data for en

import '@formatjs/intl-listformat/polyfill';
import '@formatjs/intl-listformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-pluralrules/polyfill';
import '@formatjs/intl-pluralrules/locale-data/en'; // locale-data for en

import '@formatjs/intl-numberformat/polyfill';
import '@formatjs/intl-numberformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-relativetimeformat/polyfill';
import '@formatjs/intl-relativetimeformat/locale-data/en'; // locale-data for en

import '@formatjs/intl-datetimeformat/polyfill';
import '@formatjs/intl-datetimeformat/locale-data/en'; // locale-data for en
import '@formatjs/intl-datetimeformat/add-all-tz'; // Add ALL tz data

// @ts-ignore
Date.prototype._toLocaleString = Date.prototype.toLocaleString;
Date.prototype.toLocaleString = function (a, b) {
  if (b && Object.keys(b).length === 1 && 'timeZone' in b && a === 'en-US') {
    return Intl.DateTimeFormat('en-us', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false,
      timeZone: b.timeZone,
    })
      .format(this)
      .replace(/(\d{2})\/(\d{2})\/(\d{4}),/g, '$3-$1-$2');
  }
  // @ts-ignore
  return this._toLocaleString(a, b);
};

This is just a bump/summary of the folks above - they deserve the thank you if it works for you!

Unfortunately on android when I call dayjs.tz.guess() return 'UTC' ...

Does anyone know what the problem is?

.guess is probably using some intl API that is not supported in hermes, you need to use the same that I'm using 'react-native-localize' and get the correct timezone from the native APIs

ospfranco commented 1 year ago

At least on RN 0.70 the Intl API has been implemented for Hermes on iOS. I don't know if there is some incompatibility with RN or not, but all the poly-fills and workarounds did not do anything for me. I gave up on trying to make .format('z') work the way I wanted and resorted to using a third-party package to get the timezone abbreviation.

mi-mazouz commented 1 year ago

@dlebedynskyi Working with your patch thanks!

akirchmyer commented 1 year ago

Any update on timezone plugin support for Hermes engine?

teeserted commented 1 year ago

Just adding info here that dayjs.utc(timestamp).tz(timezone).format('myformat') does not work with hermes-enabled on iOS RN 0.71. it returns 'Invalid date'. Disabling hermes enginge fixes this problem for now.

lindan4 commented 1 year ago

Has there been any update on this? I am still seeing this issue on iOS

duckhoa-uit commented 1 year ago

@troZee

create gist with patch we are using now https://gist.github.com/dlebedynskyi/81ff281b0db6aa69cdb360a1b609fb8a

this is essentially your suggested change, but as patch

+                // HACK https://github.com/iamkun/dayjs/issues/1377
+                i = Intl.DateTimeFormat('en-us', {
+                    year: 'numeric',
+                    month: '2-digit',
+                    day: '2-digit',
+                    hour: '2-digit',
+                    minute: '2-digit',
+                    second: '2-digit',
+                    hour12: false,
+                    timeZone: t,
+                })

@devinjameson

It's possible this might solve the problem on Android. In app build.gradle:

We are trying to avoid this exactly. There are bugs in current JSC used in RN related to DST (in Brazil for example). You also need to use https://formatjs.io/docs/polyfills for Hermes (RN 0.64) Last adding JSC increases your apk size by >3mb

thanks! you save my life 😭

IncrediblePony commented 1 year ago

Can confirm that this is still a problem.

VictorPulzz commented 1 year ago

This problem still actual

IncrediblePony commented 1 year ago
if ('__setDefaultTimeZone' in Intl.DateTimeFormat) {
    let RNLocalize = require('react-native-localize')
    let timeZone = RNLocalize.getTimeZone()
    try {
      Intl.DateTimeFormat.__setDefaultTimeZone(timeZone)
    } catch {
      Intl.DateTimeFormat.__setDefaultTimeZone('Etc/GMT')
    }
  }
VictorPulzz commented 1 year ago

@Aryk @IncrediblePony I tryed it, but don't working on ios (simulator) image image

VictorPulzz commented 1 year ago

I want convert from UTC to select timezone, and it doest work

IncrediblePony commented 1 year ago

Don't know what to tell you :) I wrapped my __setDefaultTimeZone(timeZone) in a trycatch and set a default/fallback timezone.

No idea what you are trying to accomplish with your code :)

VictorPulzz commented 1 year ago

@IncrediblePony The date comes from the backend in utc and I need to convert it to the timezone that the user has set, but dayjs does not want to change it via setDefault :D

vnatovskigg commented 1 year ago

The above patch causes midnight dates to be formatted as 2010-01-01 24:00:00 after applying .startOf("day") (see here) once fed into the Date constructor by the .tz implementation (see here).

24:00 marks the end of the day, leading the Date constructor to parse it as Jan 02 2010 00:00:00 GMT+0100. By replacing hour12: false with hourCycle: "h23" in the patch above the correct date is formatted / converted when using .startOf("day") in combination with timezones.

Before:

  const originalDay = dayjs("2010-01-01T00:00:00Z").tz("UTC")
  const startOfDay = originalDay.startOf("day")
  console.log(startOfDay.valueOf() === originalDay.valueOf()) // false using above patch

After:

  const originalDay = dayjs("2010-01-01T00:00:00Z").tz("UTC")
  const startOfDay = originalDay.startOf("day")
  console.log(startOfDay.valueOf() === originalDay.valueOf()) // true, using above patch with hourCycle: "h23" instead of hour12: false

Legend!

bryanltobing commented 11 months ago

still an issue up until now

blue86321 commented 11 months ago

same here. React Native 0.72.4 dayjs 1.11.10

dayjs().tz()  // return `null`
NicholasBoccuzzi commented 11 months ago

Any update?

R-D-P commented 8 months ago

I disabled Hermes and it works, I would however like to keep Hermes enabled, has anyone managed to get this to work with Hermes enabled?

dlebedynskyi commented 7 months ago

@R-D-P
you can have it with Hermes. The way we currently have it on RN 0.69

Here is current one

export function patchDate() {
    // Fix for DayJS timezone issue: 
    // https://github.com/iamkun/dayjs/issues/1377#issuecomment-1191900686
    (Date.prototype as any)._toLocaleString = Date.prototype.toLocaleString;
    Date.prototype.toLocaleString = function toLocaleStringFix(
        a?: Intl.LocalesArgument,
        b?: Intl.DateTimeFormatOptions,
    ): string {
        if (b && Object.keys(b).length === 1 && 'timeZone' in b && a === 'en-US') {
            return Intl.DateTimeFormat('en-us', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit',
                hour12: false,
                timeZone: b.timeZone,
            })
                .format(this)
                .replace(/(\d{2})\/(\d{2})\/(\d{4}),/g, '$3-$1-$2');
        }

        return this._toLocaleString(a, b);
    };
}
blue86321 commented 7 months ago

@dlebedynskyi

Thank you for your response, but how to use this patch? I run this code in my entry file App.tsx, the good news is dayjs().tz() is not null anymore. However, it gives me UTC time no matter what timezone I give. For example, dayjs.tz("America/Los_Angeles") gives me time in UTC instead of time in Los Angeles

dlebedynskyi commented 5 months ago

@blue86321 we run it ahead of dayjs, one of first line in app index.js.

KingAmo commented 4 months ago

does it cuased by https://github.com/facebook/hermes/issues/865 ?

adamjsawicki commented 3 months ago

@dlebedynskyi i am also running this before we import dayjs, and, although it returns a datetime, it is in UTC. can you share a code sample?

I have tried with both dayjs().tz(time, tz) and dayjs(time).tz(tz), both to no avail.

Thanks!

chunghn commented 3 months ago

Same issue. tz return null in react native.

almiavicas commented 2 months ago

For those who are having issues when converting timezones (dayjs().tz(timeZone)), the issue is the Hermes engine. You can disable it for Android at android/gradle.properties:

# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=false

for iOS, the file is ios/PodFile:

use_react_native!(
    :path => config[:reactNativePath],
    # to enable hermes on iOS, change `false` to `true` and then install pods
    :hermes_enabled => false
  )
dlebedynskyi commented 2 months ago

@adamjsawicki my patch did not change much.

import once from 'lodash/once';

function patchDate() {
    (Date.prototype as any)._toLocaleString = Date.prototype.toLocaleString;
    Date.prototype.toLocaleString = function toLocaleStringFix(
        a?: Intl.LocalesArgument,
        b?: Intl.DateTimeFormatOptions,
    ): string {
        if (b && Object.keys(b).length === 1 && 'timeZone' in b && a === 'en-US') {
            return Intl.DateTimeFormat('en-us', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit',
                hour12: false,
                timeZone: b.timeZone,
            })
                .format(this)
                .replace(/(\d{2})\/(\d{2})\/(\d{4}),/g, '$3-$1-$2');
        }

        return this._toLocaleString(a, b);
    };
}

export const patch = once(patchDate);

then just call patch early in your startup. Note - we are still at dayjs@1.11.7

andrei-ce commented 1 month ago

Still an issue, thank you @dlebedynskyi and @sohcah for the polyfills. And @dortamiguel for posting this!