Base solution for your next web application
Open Closed

Arabic locale Issue #4547


User avatar
0
kasem created

Hi

Switching to Arabic changes Dates to to Hijri format. I want them in Gregorian. Also numbers appear in Hindu and I want them in a different locale.

Can I switch to Arabic translation while keeping Dates, Numbers and Currency in English or some other locale ?

Thanks


19 Answer(s)
  • User Avatar
    0
    kasem created

    UPDATE: I think I've managed this by changing locale of Angular and MomentJs. For Angular I added mappings between Arabic and the targeted locale through LocaleMapping. And the same I'm going to do with moment locale

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Kasem,

    Sorry for our late response. Your first solution is correct for Angular. That mapping is not used for moment but the language you have selected must be in use for moment. Please share your final result with us.

    Thanks.

  • User Avatar
    0
    kasem created

    Hi @ismcagdas

    Angular I just added the following mapping in AppConfig:

    {
          "from": "ar",
          "to": "en"
        }
    

    Moment I added a helper method that takes care of mapping Moment locale in AppPreBootstrap. In my case ar-kw was fine:

    public static mapCultureForMoment(currentCulture: string): string {
            const cultureMap = {
                'ar': 'ar-kw'
            };
    
            if (cultureMap[currentCulture]) {
                return cultureMap[currentCulture];
            }
    
            return currentCulture;
        }
    

    I still have something to update to reflect this on Date format Pipe

  • User Avatar
    0
    kasem created

    After solving the frontend part, I noticed that Hijri date is still resolved from BE, and nothing to do now with frontend. Can you please guide me to the right place to change this on BE without affecting the translation to Arabic on BE.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    I noticed that Hijri date is still resolved from BE

    Sorry but I couldn't understand the "BE", can you explain it ?

  • User Avatar
    0
    kasem created

    Sorry I mean Backend :)

  • User Avatar
    0
    ismcagdas created
    Support Team

    Ok, got it now :).

    When selecting a language, it is set on the server side like this:

    Thread.CurrentThread.CurrentCulture = CultureInfoHelper.Get(language);
    Thread.CurrentThread.CurrentUICulture = CultureInfoHelper.Get(language);
    

    In your case, easiest option is sending "en" to server instead of "ar" when user changes the language. You can use localeMappings for this.

    A better solution would allow user to select UI Culture and Culture seperately on the UI.

  • User Avatar
    0
    kasem created

    Thank you. I'll try it, but I think this will affect the Arabic translation in server side which is something I'm not interested in. I don't want to affect the translation on frontend and backend, but only change Locale related to Dates, Currency, etc.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Kasem,

    I haven't tried but you can try this on the server side.

    Thread.CurrentThread.CurrentUICulture.DateTimeFormat = new CultureInfo("en-US").DateTimeFormat;
    

    This will only change the date format but not anything else.

  • User Avatar
    0
    kasem created

    Hi @ismcagdas

    I was able to add the needed configurations that meet my needs, however I'm still experiencing a problem that's only backend related. When I watch the values during debugging I see the date resolved exactly as needed, but when it returns it from the service to client, it's returned again as Hijri. (I even tried it through POSTMAN to avoid any client side effects)

    So I guess it's sort of OWIN Middleware you injected that changes Culture in the pipeline. I noticed you have a method called ThreadCultureSanitizer that's injected in your UseAbp OWIN extension, not sure if it's the right place.

    I need your help please to know how and where I can override this behavior. (Note again please that I only use AspNetZero and I don't maintain the source of Abp)

    Thanks

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Kasem,

    I couldn't be sure if the cause of the problem is ThreadCultureSanitizer or not. But if you think it is the problem, you can add below line as the first line of ConfigureOwinServices method.

    Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
    

    You can also use this line instead of using my previous suggestion

    Thread.CurrentThread.CurrentUICulture.DateTimeFormat = new CultureInfo("en-US").DateTimeFormat;
    

    Maybe a different property of Thread.CurrentThread.CurrentUICulture is used for datetime serialization.

  • User Avatar
    0
    kasem created

    Thanks @ismcagdas

    Unfortunately, it didn't work for me yet.

    I'll provide an example that may help you reproduce it at your side:

    1. Make your language Arabic

    2. Add the culture changing code first lines of any method that returns datetime (like a DTO that inherit from FullAuditedEntityDto) something like: GetSomethingForEdit()

    3. Observe FirstOrDefaultAsync method result to see the datetime values like CreationTime (you should get it Gregorian not Hijri)

    4. Then check the result returned to client side (you'll get it Hijri again)

    So there are two problems I'm looking for a solution for:

    1. Apply the needed Culture configs somewhere that's applied everywhere in the app
    2. is the most critical issue, that something changes Culture when it's back from server to client

    Thanks

  • User Avatar
    0
    kasem created

    I think I've solved the first issue by adding Culture date configs in ..AppServiceBase constructor Waiting your feedback about other issue

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Kasem,

    Last thing comes to my mind is moment. Can you set it's locale to "en" here as well.

    <a class="postlink" href="https://github.com/aspnetzero/aspnet-zero-core/blob/dev/angular/src/AppPreBootstrap.ts#L143-L144">https://github.com/aspnetzero/aspnet-ze ... #L143-L144</a>

  • User Avatar
    0
    kasem created

    Thanks @ismcagdas

    I already have those configurations applied sometime ago, and it helped solve the problem on frontend only.

    // moment.locale(abp.localization.currentLanguage.name);
    //  (window as any).moment.locale(abp.localization.currentLanguage.name);
    let momentLocale = LocalizedResourcesHelper.mapCultureForMoment(abp.localization.currentLanguage.name);
    moment.locale(momentLocale);
    (window as any).moment.locale(momentLocale);
    
    public static mapCultureForMoment(currentCulture: string): string {
            const cultureMap = {
                'ar': 'en'
            };
    
            if (cultureMap[currentCulture]) {
                return cultureMap[currentCulture];
            }
    
            return currentCulture;
        }
    

    The reason I say it's only backend, because for some reason, CreationTime is stored in database the correct way now (Gregorian). But when I try to edit the record, it's converted to Hijri (on backend only) and returned to client as Hijri. The steps I provided will show exactly what I mean.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Kasem,

    I reproduced your problem. Here is a workaround;

    1. First create a class like below in your *.Web.Host project:
    public class MyRequestCultureProvider : RequestCultureProvider
    {
    	public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
    	{
    		var result = new ProviderCultureResult(culture: (StringSegment)"en-US", uiCulture: (StringSegment)"ar");
    		return Task.FromResult(result);
    	}
    }
    

    Then, use it like this to see if server returns dates with correct format:

    app.UseAbpRequestLocalization(opts =>
    {
    	opts.RequestCultureProviders.Insert(0, new MyRequestCultureProvider());
    });
    

    But, this will work before all request culture providers, so when you change the language on the UI, it will not work. So, you need to execute other request culture localizers in your custom class (like this one <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/master/src/Abp.AspNetCore/AspNetCore/Localization/AbpUserRequestCultureProvider.cs">https://github.com/aspnetboilerplate/as ... rovider.cs</a>), then determine correct uiCulture.

  • User Avatar
    0
    kasem created

    Awesome! It works just perfect now. I also followed your instructions to update the part that's required for language switching and everything just working as expected.

    Thanks a million!

  • User Avatar
    0
    alwefaq created

    @Kasem Hi, I hope you are doing well :) I am facing the same issue , Could you please clarify which places you did your changes either front-end or server side with sample codes so, i can fix it on our solution :)

  • User Avatar
    0
    bosalah created
    • 1 please help angular 8 asp core 3 pro I am facing the same issue , Could you please clarify which places you did your changes either front-end or server side with sample codes so, i can fix it on our solution :)