Get language and country code (ISO 639-1) - c#

Is there a solution for xamarin-ios to get the current culture in the format like (en_US, de_CH, ..)? I read so many articles in the web and here on stackoverflow. But I can't find a nice solution for this.
Following code snippet returns not this format everytime. Sometimes I get "gsw_DE" and so on (ISO 639-2 instead of 639-1)
NSLocale.CurrentLocale.Identifier;
My current solution is to do it by myself:
var languagecode = NSLocale.PreferredLanguages[0];
var result = String.Format("{0}_{1}", languagecode.Substring(0, 2), NSLocale.CurrentLocale.CountryCode);
Above workaround is from: Get iOS current language (including country code)
I need to make sure that I get the value in this format.
Is there another way? Thanks

We are still in the C# world, aren't we?
You can use CultureInfo.CurrentUICulture.Name and it'll give you "en-US" for "default" English and "en-GB" for English UK. Language settings are in General - Language & Region - iPhone Language.

Related

Convert int to Arabic number string in UWP

I'm trying to use String.Format to convert an integer into a string, but I need the number to reflect the current culture for languages with classical shapes (such as Arabic and Thai). This was previously possible in WPF, but UWP seems to be missing DigitShapes (even though System.Globalization.CultureInfo.CurrentCulture is still available). Anyone know a workaround for this in UWP?
I think I found a solution. The NumeralSystemTranslator class is supported in UWP. It's not as easy as I was hoping, but if you set the NumeralSystemTranslator.NumeralSystem property manually (it's Latin by default), it will return the native characters for numbers for the locale you specify. The List of values is here.
So, for Arabic, you'd do:
NumeralSystemTranslator translator = new NumeralSystemTranslator();
translator.NumeralSystem = "Arab";
string output = translator.TranslateNumerals("5");
Took me a while to track this down. Hope it's helpful to someone else as well :)

Microsoft translator nb-NO translates fine, but supported language api call does not list as supported language

I would like to check if a language is supported by Microsoft Translator, before sending the request of to translate text.
I make a call to this api:
http://api.microsofttranslator.com/V2/Http.svc/GetLanguagesForTranslate
and it returns a list of languages. One of them is: "no" for Norweigan.
My application has support for nb-NO... so my language check essentially comes down to this code:
string language = "nb-NO";
this.cachedSupportedLanguages = string[] { "no" };
return this.cachedSupportedLanguages.Contains(language);
The issue i'm having is if i send the request off to this api with nb-NO as the "to Language", the translation falls back to Norweigan:
http://api.microsofttranslator.com/v2/Http.svc/Translate?text=textToTranslate&from=fromLanguage&to=toLanguage ...
...but I cannot find a way of pre-checking if a language is supported because even if i do:
new CultureInfo(language)
It doesn't have any knowledge of the language being able to fall back to Norweigan.
Any ideas how i can check this in a better way than an explicit switch?
Edit
The cultures have a hierarchy, such that the parent of a specific
culture is a neutral culture and the parent of a neutral culture is
the InvariantCulture. The Parent property returns the neutral culture
associated with a specific culture.
https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo(v=vs.71).aspx
If i do this:
CultureInfo cultureInfo = new CultureInfo(language);
// For languages like en-US
if (this.cachedSupportedLanguages.Any(x => x.Equals(cultureInfo.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase)))
{
return true;
}
// For languages like nb-NO where the explicit language is not supported but its parent culture is
if (!string.IsNullOrEmpty(cultureInfo.Parent.ToString()))
{
if (cultureInfo.Parent.IsNeutralCulture)
{
if (!string.IsNullOrEmpty(cultureInfo.Parent.Parent.ToString()))
{
if (!string.IsNullOrEmpty(cultureInfo.Parent.Parent.CompareInfo.ToString()))
{
return this.cachedSupportedLanguages.Any(x => x.Equals(cultureInfo.Parent.Parent.CompareInfo.Name, StringComparison.OrdinalIgnoreCase));
}
}
}
}
I get a true... But i do not fully understand if the Parent is always going to be a safe bet to go to for this information?
There is a Microsoft translator method that returns the information you need. The data is returned as JSON. You can get supported languages for text translation, speech translation and text to speech in one api call. You also get more information.
Learn about it and try it out at: http://docs.microsofttranslator.com/languages.html
GetLanguagesForTranslate returns nb for Norwegian, not no as stated in the post. Go to http://docs.microsofttranslator.com/languages.html, click Try it, and see this in the result:
"nb": {
"name": "Norwegian",
"dir": "ltr"
},
One approach would be to keep a table with the result of the GetLanguagesForTranslate. First look up your culture code directly, and if no match, then look for a match on the Parent. Parent should be reliable for this purpose. This will let your code work for those supported languages like sr-Cyrl, sr-Latn, zh-Hans, and zh-Hant, and fall back to the neutral when the qualified name isn't available.

Localization on Xamarin.iOS

I'm trying to figure out localization on Xamarin.iOS. I am new to localization in general, but the first language we want to do is Icelandic. If you look on the settings for the iOS device itself Icelandic is not an option. So this is a two part question.
How can I set up localization within my app? Do I just localize in the same manner as other .net apps..or is there something specific to iOS/Xamarin that I need to do.
Once I implement this, how do I get it to choose Icelandic as the language since iOS does not have it as an available language?
Documentation seems to be sparse on this topic.
How can I set up localization within my app?
iOS has its own way to handle localizations. For each language you need to create a folder in your project named language.lproj where language is ISO 639-1 or ISO 639-2 language code. Two character ISO 639-1 codes are preferred (e.g. en, de, fr, it, ...). You can find a table with ISO 639-1 and ISO 639-2 codes here.
In your newly created folder you need to create a file named Localizable.strings and here you can add your strings which you want to localize:
"stringToLocalize" = "This is the translation";
And to assign a localized string for example to a UILabel:
UILabel label = new UILabel();
...
label.Text = NSBundle.MainBundle.LocalizedString("stringToLocalize", null);
You can even create an extension method (credit to anotherlab):
public static class LocalizationExtensions
{
public static string t(this string translate)
{
return NSBundle.MainBundle.LocalizedString(translate, "", "");
}
}
How do I get it to choose Icelandic as the language since iOS does not have it as an available language?
I don't think there is a way to choose Icelandic as a language in iOS. One of our apps uses German, Italian and French localizations. Since we don't need English we created en.lproj folder with German localizations in it. This way even if the language of the device is set to English, German texts will appear. Maybe you can do something like this too in your app.

WinRT apps and Regional settings. The correct way to format dates and numbers based on the user's regional settings?

I'm having some problems in Windows 8 Metro apps (XAML & C#) regarding the user's regional settings. It seems that the apps won't respect user's regional settings, so even if your Windows 8 is set to display dates and times in Finnish format, the apps will still display them using US-formatting. But this is such a big problem that there must be something I'm missing?
To test this I started by creating a WPF-application. The application just prints out the CurrentCulture and the formatted DateTime.Now:
private void Culture_Loaded_1(object sender, RoutedEventArgs e)
{
this.Culture.Text = System.Globalization.CultureInfo.CurrentCulture.DisplayName;
}
private void Date_Loaded_1(object sender, RoutedEventArgs e)
{
this.Date.Text = DateTime.Now.ToString();
}
Here's my default regional settings:
When run, the app displayed the date in Finnish format:
Then I changed the regional settings to US:
And when the app was run again, the culture and formatting changed:
This is as I expected everything to work and this is also how I expected WinRT apps to work.
So as a next step, I created a WinRT (XAML & C#) app with the same code and reverted the regional settings back to Finnish. The problem:
Even when I've defined through regional settings that the formatting should be "Finnish", the WinRT app displays the datetime with US-formatting. I then modified the app's project file and made fi-FI the default language:
This change also modified the app's culture:
Strange. I changed the Default Language back to its default value and the formatting was restored to US. I then created folders "Strings - fi-FI" inside the project and added an empty "Resources.resw" to the project. This empty file seems to be enough, as I was now getting the Finnish formatting:
As soon as I remove the empty resource file, the formattings reverts back to US:
Very strange.
This leads to few questions, but the main one I think is: Is it intentional that the WinRT-apps don't follow the user's regional settings like the WPF apps do?
It's been a while, but the question is not fully answered, so let me share my little research. Depechie is mostly right, but he provided only a link and wasn't really sure.
Yes, this unexpected change is intentional. We shouldn't use CultureInfo anymore as it contains legacy codes and Microsoft want us to use Windows.Globalization APIs instead.
To obtain current region we can use:
GeographicRegion userRegion = new GeographicRegion();
string regionCode = userRegion.CodeTwoLetter;
But as I noticed it contains only region information, there's no language code. To obtain language we can use:
string langRegionCode = Windows.Globalization.Language.CurrentInputMethodLanguageTag; // depends on keyboard settings
List<string> langs = Windows.System.UserProfile.GlobalizationPreferences.Languages; // all user languages, like in languages control panel
List<string> applicationlangs = Windows.Globalization.ApplicationLanguages.Languages; // application languages (user languages resolved against languages declared as supported by application)
They return BCP47 language tags in format language-REGION like "en-US" if language has dialects or just language like "pl" if the language doesn't have major dialects.
We can also set one primary language which will override all the rest:
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "en-US";
(This is a persisted setting and is supposed to be used at user request)
There is also new API for date, time and numbers:
Windows.Globalization.DateTimeFormatting.DateTimeFormatter dtf = new DateTimeFormatter("longdate", new[] { "en-US" }, "US", CalendarIdentifiers.Gregorian, ClockIdentifiers.TwentyFourHour);
string longDate = dtf.Format(DateTime.Now);
Windows.Globalization.NumberFormatting.DecimalFormatter deciamlFormatter = new DecimalFormatter(new string[] { "PL" }, "PL");
double d1 = (double)deciamlFormatter.ParseDouble("2,5"); // ParseDouble returns double?, not double
There's really a lot more in Windows.Globalization APIs, but I think that this gives us the general idea. For further reading:
date & time formatting sample:
http://code.msdn.microsoft.com/windowsapps/Date-and-time-formatting-2361f348/sourcecode?fileId=52070&pathId=561085805
number formatting & parsing sample:
http://code.msdn.microsoft.com/windowsapps/Number-formatting-and-bb10ba3d/sourcecode?fileId=52249&pathId=1462911094
there's also a nice article titled "How to use patterns to format dates and times" on msdn, but I can add only 2 links
You can also find some topics about the issue on windows 8 dev center forum with some Microsoft employee answers, but they mainly send you to the documentation.
It is intentional. Microsoft is moving away from forcing applications to be in the language of the OS. Instead, each application uses information declared by the application (manifest languages, observable at Windows.Globalization.ApplicationLanguages.ManifestLanguages) and declared by the user (user languages, observable at Windows.System.UserProfile.GlobalizationPreferences.Languages) to determine how to display resources and globalized dates and times. This set of languages is called the application languages (observable at Windows.Globalization.ApplicationLanguages.Languages). The behavior you are seeing is because you are fiddling with the user languages and the manifest languages and you will get different application languages.
Could it be we now need to query other classes? Like the example given here: http://code.msdn.microsoft.com/windowsapps/Globalization-preferences-6654eb36/sourcecode?fileId=52104&pathId=236099476
This post still seems to be relevant even though it was asked two years ago.
I just came across it as I was looking for an answer to about the same thing.
I also wanted to display dates in the regional format in my WP8.1 WinRT app.
The information posted here helps, but it was a bit hard to piece it together.
This is what I came up with and it seems to work for me as the answer I needed:
using Windows.Globalization;
using Windows.Globalization.DateTimeFormatting;
private string FormatDate(int year, int month, int day)
{
GeographicRegion userRegion = new GeographicRegion();
string regionCode = userRegion.CodeTwoLetter;
var formatter = new DateTimeFormatter("year month day", new[] { regionCode });
DateTime dateToFormat = new DateTime(year, month, day);
var formattedDate = formatter.Format(dateToFormat);
return formattedDate;
}

Why is the culture name for English (Caribbean) "en-029"?

Why is the culture name for English (Caribbean) "en-029"?
I know "en-CA" is used for English (Canada), but why 029? What does it signify? Why was it chosen?
Michael Kaplan (aka Microsoft's Unicode guru) just wrote a blog post about that last week.
EDIT
And actually, if you read the comments you'll see that 029 isn't even an ISO 3166 code because ISO 3166 is only about countries. That's where UN M.49 comes in which defines codes that specify:
a wide variety of geographical, political, or economic regions, like a
continent, a country, or a specific “group of developing countries”.
And that's where you get code 029 for Caribbean.
It might have something to do with country area codes assigned by United Nations.
I might be wrong but I believe there is more than one country in the Caribbean area, therefore MS decided to assign the territory code rather than specific symbol (the latter probably is not registered).

Categories

Resources