DateTime.ToString() throws ArgumentOutOfRangeException in Thai locale

ben.laceyben.lacey USMember ✭✭

Hi,

We're seeing an issue when our app is being used on iOS when in the Thai locale, seemingly down to the DateTime.ToString() method throwing an ArgumentOutOfRangeException with the message "Not a valid calendar for the given culture".

It is only reproducible on a physical iOS device set to the Thai language/locale - when running in a simulator in the same setup the issue is not present. The same code in an Android project running on a device set to Thai also does not throw the exception.

Here's an example stack trace that shows the exception we receive - this one for example, is when we inspect the headers of an HTTP response:

System.ArgumentOutOfRangeException: Not a valid calendar for the given culture. Parameter name: value at System.Globalization.DateTimeFormatInfo.set_Calendar (System.Globalization.Calendar value) [0x0014e] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/external/referencesource/mscorlib/system/globalization/datetimeformatinfo.cs:712 at System.Globalization.DateTimeFormatInfo..ctor (System.Globalization.CultureData cultureData, System.Globalization.Calendar cal) [0x00022] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/external/referencesource/mscorlib/system/globalization/datetimeformatinfo.cs:359 at System.Globalization.CultureInfo.get_DateTimeFormat () [0x0002d] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/mcs/class/corlib/System.Globalization/CultureInfo.cs:531 at System.Globalization.CultureInfo.GetFormat (System.Type formatType) [0x00038] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/mcs/class/corlib/System.Globalization/CultureInfo.cs:586 at System.Globalization.DateTimeFormatInfo.get_CurrentInfo () [0x00027] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/external/referencesource/mscorlib/system/globalization/datetimeformatinfo.cs:530 at System.DateTimeOffset.ToString () [0x00000] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/external/referencesource/mscorlib/system/datetimeoffset.cs:607 at System.Net.Http.Headers.HttpHeaders+HeaderBucket.ParsedToString () [0x0002a] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs:80 at System.Net.Http.Headers.HttpHeaders.GetAllHeaderValues (System.Net.Http.Headers.HeaderBucket bucket, System.Net.Http.Headers.HeaderInfo headerInfo) [0x00030] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs:411 at System.Net.Http.Headers.HttpHeaders+<GetEnumerator>c__Iterator0.MoveNext () [0x0009b] in /Users/builder/data/lanes/1503/e6ebd18b/source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs:298 at System.Linq.Enumerable.Any[KeyValuePair'2] (IEnumerable'1 source) [0x00024] in //Library/Frameworks/Xamarin.iOS.framework/Versions/8.10.1.64/src/mono/mcs/class/System.Core/System.Linq/Enumerable.cs:138 at ... [snip]

The only workaround we've managed to get working is setting the CultureInfo.DefaultThreadCurrentCulture to the InvariantCulture in the Main method of the app, which fixes all usages of ToString() even in libraries as above, though means any culture-specific formatting has to be done explicitly.

I've attached a small repro project that shows the issue - it'll perform a DateTime.ToString() method using a few different cultures, including th-TH which should show the issue.

Is there any advice you can give us on this? It looks to be a bug deep down in Mono, maybe?

Posts

  • ChristerNordvikChristerNordvik NOMember

    Also just saw this bug from our Thai users so I think it was introduced recently.

  • Alex.litvinenkoAlex.litvinenko USMember ✭✭

    hi, got same issue with Thai and Arabic.
    For Thai solved it in funny way, just by adding this line in AppDelegate.FinishedLaunching()
    var thai = new System.Globalization.ThaiBuddhistCalendar ();

    any hotfix for arabic?

  • ChristerNordvikChristerNordvik NOMember
    edited June 2015

    If you go to build->advanced and include the various calendars then it works. Not sure if "west", "rare" or "other" needs to be included though :-/

    https://bugzilla.xamarin.com/show_bug.cgi?id=30897

  • jamie94bcjamie94bc GBMember
    edited August 2015

    The hotfix for Arabic would be System.Globalization.PersianCalendar().

    I'm presuming this does the same as checking the various calendars by detecting the calendars are used when compiling. Can anyone confirm that?

    This only became an issue recently - for both Android and iOS.

  • jamie94bcjamie94bc GBMember

    Scrap that, completely wrong locale - should be UmAlQuraCalendar.

    Is there any guidance around the Internationalization setting yet / whether this is actually a bug? The issue on bugzilla is marked as confirmed but no target release.

  • I confirm having this with Arabic locale/region and only on device and on release builds only .. any fixes ?

  • Dana.LatitudeDana.Latitude CAMember ✭✭

    This error is still happening in Release Builds as of March 2016.

  • Dana.LatitudeDana.Latitude CAMember ✭✭

    I got the application to work on iOS by including the various calendars (xamarin studio: build->advanced -> include all calendars)
    However, I can't get the same to happen in Android (for which I'm using Visual Studio). To add the calendars, from my understanding, I have to change the csproj file and add either add CJK;Mideast;Other;Rare;West or All (as described here https://developer.xamarin.com/guides/android/under_the_hood/build_process/ ) . Am I missing something? Did anyone get this method to work on Android?

    Thank you,
    Dana

  • AndrewBaresAndrewBares USMember

    Anyone get this working in Android?

  • ThibaultDThibaultD SEMember ✭✭✭

    TL;DR: Always specify the culture in your DateTime.ToString calls.

    I thought it was best-practice to always specify the InvariantCulture when using DateTime.ToString(). I always do.

    I stumbled upon this issue because I forgot to do it only once and experienced this crash on an iPhone with Arabic locale.

    Save yourself some pain, always do:

    var now = DateTime.Now;
    var todayString = now.ToString("yyyy'-'MM'-'dd", CultureInfo.InvariantCulture);
    

    Especially if you are not going to show this string to your user.

    To find ToString usages that don't use the InvariantCulture in all your code (using bash)(disclaimer: Won't catch ToString with no argument but easy to change it):

    find . -type f -name "*.cs" -print0 | xargs -0 grep -n -E "\.ToString\([^)+]" | grep -v InvariantCulture
    
  • PetrikDavidPetrikDavid CZMember ✭✭
    edited May 30

    So is there still no solution for Android, other than reference the calendar type in code to make the linker include it?
    As @Dana.Latitude mentioned, the MandroidI18n tag in csproj (a.k.a. "Additional supported encodings" option in project "Android Options") isn't helping. (I presume it only makes encoding pages included?).

Sign In or Register to comment.