Parsing three-letter language names as culture info
Asked Answered
V

4

8

I'm working with an API that returns some information about audio streams in a file, more specifically the audio language in its three-letter ISO name (ISO 639-2) representation.

I would like to parse this information into a new CultureInfo object, but there is no constructor that takes a three-letter code. I could of course write an enormous select statement (switch for you C# people), but I figured it would be more cost-efficient to ask around for a better way first. So am I out of luck or is there a secret way to create a CultureInfo object using three letter names?

Valora answered 23/3, 2012 at 14:36 Comment(1)
I don't think there is a good way to go in the opposite direction. For example, eng can range anywhere from en-029 to en-ZW. How would you expect this to behave if you read eng?Hylo
B
11

EDIT: sorry, I've used the wrong property:

public static CultureInfo FromISOName(string name)
{
    return CultureInfo
        .GetCultures(CultureTypes.NeutralCultures)
        .FirstOrDefault(c => c.ThreeLetterISOLanguageName == name);
}

However, there are still duplicates in the list and no support for "dut".

Beliabelial answered 23/3, 2012 at 15:4 Comment(3)
Close, but no cigar. :( It fails when there is more than one letter code for the same language (example: both "dut" and "nld" are used for Dutch, the framework doesn't recognise "dut"). Apparently Microsoft chose to include only one letter code per language, very unfortunate.Valora
I'll mark this as the answer as it's the closest it will get with the current framework implementation of ISO 639-2 codes.Valora
I've discovered that there are only 21 languages that have both a bibliographic code and a terminology code. It's not too much effort to convert between the two and this method works fine after conversion.Valora
L
2

I would go for Balazs solution, but it would be better in your case to use CultureTypes.NeutralCultures as you don't seem to be concerned with region/country data.

It would always return a single CultureInfo with no need of FirstOrDefault

Lutes answered 23/3, 2012 at 15:12 Comment(0)
K
0

There is nothing built in that will help with such parsing.

Instead of a select, you can create a Dictionary(Of string, CultureInfo) to map from one to the other. This is more as an ease of use suggestion.

Klaus answered 23/3, 2012 at 14:47 Comment(0)
P
0

Here is an extension method for the Silverlight System.Globalization.CultureInfo class, that gets the ISO 639-2 three-letter code for the language of the current System.Globalization.CultureInfo object. It uses ISO-639-2 table, that is retrieved via Utils.GetResourceStream() custom method.

The implementation also relies on a custom String.NthIndexOf() method.

public static string ThreeLetterISOLanguageName(this CultureInfo cultureInfo)
{
    const string separator = "|";

    using (var reader = new StreamReader(Utils.GetResourceStream("ISO-639-2_utf-8.txt")))
    {
        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();
            //two-letter ISO code is in the third column, i.e. after the second separator character
            string twoLetterISOCode = line.Substring(line.NthIndexOf(separator, 1) + separator.Length, 2);
            if (!twoLetterISOCode.Equals(cultureInfo.TwoLetterISOLanguageName)) continue;
            return line.Substring(0, 3);
        }
    }

    return null;
}

Full Gist

Polygamous answered 14/8, 2013 at 9:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.