C# CultureInfo tutorial
last modified July 5, 2020
C# CultureInfo tutorial shows how to globalize appications in C# with CultureInfo. C# tutorial is a comprehensive tutorial on C# language.
Globalization is the process of designing the application in such a way that it can be used by users from across the globe (for multiple cultures). Localization is the process of customizing the application to a specific culture.
Types of cultures
Neutral culture is a culture that is associated with a language but
not with a country or region. Specific culture is a culture that is
associated with both a language and a country or region. For example, fr
is the
name for the neutral French culture, while fr-FR
is the name for the French
culture in France.
Invariant culture is culture-insensitive; it is associated with the
English language (for historical reasons) but not with any country/region. We
specify the invariant culture by name by using an empty string ("") in the call
to a CultureInfo
instantiation method.
CultureInfo.InvariantCulture
also retrieves an instance of the
invariant culture. Invariant culture is used for storing strings from a variety of
cultures in a way where they are not tied to any language or culture. For instance,
we can use invariant culture when persisting dates and times.
C# CultureInfo
CultureInfo
provides information about a specific culture. The
information includes the names for the culture, the writing system, the calendar
used, the sort order of strings, and formatting for dates and numbers.
using System.Globalization;
The CultureInfo
is part of the System.Globalization
namespace.
C# current culture
The CultureInfo.DefaultThreadCurrentCulture
property gets
or sets the default culture for threads in the current application domain.
using System; using System.Globalization; namespace CurrentCulture { class Program { static void Main(string[] args) { double val = 1235.56; Console.WriteLine($"Current culture: {CultureInfo.CurrentCulture.Name}"); Console.WriteLine(val); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-DE"); Console.WriteLine($"Current culture: {CultureInfo.CurrentCulture.Name}"); Console.WriteLine(val); } } }
The example prints a value in two cultures.
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-DE");
We set the default culture to de-DE
.
$ dotnet run Current culture: en-US 1235.56 Current culture: de-DE 1235,56
This is the output. The two values have different decimal separators.
C# list cultures
The CultureInfo.GetCultures()
gets the list of supported cultures
filtered by the specified culture type parameter.
using System; using System.Globalization; namespace ListCultures { class Program { static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; Console.WriteLine("{0,-15}{0,-5}{0,-45}{0,-40}", "Culture", "ISO", "Display name", "English Name"); foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures)) { Console.Write("{0,-15}", ci.Name); Console.Write("{0,-5}", ci.TwoLetterISOLanguageName); Console.Write("{0,-45}", ci.DisplayName); Console.WriteLine("{0,-40}", ci.EnglishName); } } } }
The example lists all installed .NET cultures.
Console.OutputEncoding = System.Text.Encoding.UTF8;
To be able to show various display names of cultures, we set the output encoding to UTF8. In addition, the terminal must have a font that is able to display all these languages.
With the CultureTypes.SpecificCultures
filter parameter, we get all
specific cultures. With CultureTypes.NeutralCultures
, we get all
neutral cultures.
using System; using System; using System.Globalization; using static System.Globalization.CultureTypes; namespace Cultures { class Program { static void Main(string[] args) { CultureInfo[] specificCultures = CultureInfo.GetCultures(SpecificCultures); Console.WriteLine($"{specificCultures.Length} specific cultures in .NET"); CultureInfo[] neutralCultures = CultureInfo.GetCultures(NeutralCultures); Console.WriteLine($"{neutralCultures.Length} neutral cultures in .NET"); } } }
The example prints the number of specific and neutral cultures in .NET.
$ dotnet run 569 specific cultures in .NET 279 neutral cultures in .NET
This is the output.
C# invariant culture
Invariant culture is culture independent. We use it when we persist culture information, such as dates. Saving dates in culture-independent way allows us to parse the values later easily.
using System; using System.IO; using System.Globalization; namespace InvariantCulture { class Program { static void Main(string[] args) { CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); DateTime[] dates = { new DateTime(2019, 10, 9), new DateTime(2020, 1, 2) }; using var sw = new StreamWriter(@"C:\Users\Jano\Documents\tmp\dates.dat"); sw.Write(String.Format(CultureInfo.InvariantCulture, "{0:d}|{1:d}", dates[0], dates[1])); } } }
The example writes two dates with CultureInfo.InvariantCulture
format.
sw.Write(String.Format(CultureInfo.InvariantCulture, "{0:d}|{1:d}", dates[0], dates[1]));
We pass the CultureInfo.InvariantCulture
to the String.Format()
method.
$ cat C:\Users\Jano\Documents\tmp\dates.dat 10/09/2019|01/02/2020
This are the file contents.
using System; using System.IO; using System.Globalization; namespace InvariantCulture2 { class Program { static void Main(string[] args) { using var sr = new StreamReader(@"C:\Users\Jano\Documents\tmp\dates.dat"); string contents = sr.ReadToEnd(); string[] dateStrings = contents.Split('|'); Console.WriteLine($"Current Culture: {CultureInfo.CurrentCulture.Name}"); foreach (var dateStr in dateStrings) { DateTime dateVal; if (DateTime.TryParse(dateStr, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateVal)) { Console.WriteLine("The date is {0:D}", dateVal); } else { Console.WriteLine("ERROR: Unable to parse {0}", dateStr); } } Console.WriteLine(); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("sk-SK"); Console.WriteLine($"Current Culture: {CultureInfo.CurrentCulture.Name}"); foreach (var dateStr in dateStrings) { DateTime dateVal; if (DateTime.TryParse(dateStr, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateVal)) { Console.WriteLine("Dátum je {0:D}", dateVal); } else { Console.WriteLine("ERROR: Unable to parse {0}", dateStr); } } } } }
In the example, we restore the data and display the dates in two different cultures.
if (DateTime.TryParse(dateStr, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateVal)) { ...
We pass the CultureInfo.InvariantCulture
as the second
paramter of the TryParse()
method.
$ dotnet run Current Culture: en-US The date is Wednesday, October 9, 2019 The date is Thursday, January 2, 2020 Current Culture: sk-SK Dátum je streda 9. októbra 2019 Dátum je štvrtok 2. januára 2020
This is the output.
C# CultureInfo sorting
Sorting strings is culture specific. Setting the correct culture for the language will do the correct sorting.
using System; using System.Globalization; using System.Collections.Generic; namespace Sorting { class Program { static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("sk-SK"); var words = new List<string> { "čaj", "auto", "drevo", "cibuľa", "čučoriedka", "banán", "čerešňa", "červený", "čierny", "cesnak" }; words.Sort(); foreach (var word in words) { Console.WriteLine(word); } } } }
The example has a list of Slovak words. Setting the correct culture will sort the words according to the rules of the Slovak language.
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("sk-SK");
We set the Slovak culture.
var words = new List<string> { "čaj", "auto", "drevo", "cibuľa", "čučoriedka", "banán", "čerešňa", "červený", "čierny", "cesnak" };
We have a list of Slovak words.
words.Sort();
We sort the words. The Sort()
method takes the culture into
account when sorting the data.
$ dotnet run auto banán cesnak cibuľa čaj čerešňa červený čierny čučoriedka drevo
This is the output. In the Slovak language, the č letter goes after the c letter. English sorting would not make a difference between these two letters.
C# CultureInfo decimal separator
Cultures use decimal point (Israel, Japan, UK) or comma (Slovakia, France, Germany) as decimal separators. Persian uses a forward slash (/).
using System; using System.Globalization; namespace DecimalSeparator { class Program { static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; double val = 1278.112; CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("sk-SK"); Console.WriteLine($"{val}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); Console.WriteLine($"{val}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("fa-IR"); Console.WriteLine($"{val}"); } } }
The example prints a decimal value in three different cultures.
$ dotnet run 1278,112 1278.112 1278/112
This is the output.
C# CultureInfo thousands separator
Cultures use different ways to group digits with a delimiter for ease of reading.
using System; using System.Globalization; namespace ThousandsSeparator { class Program { static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; int val = 12_156_320; CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("sk-SK"); Console.WriteLine($"{val:N}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); Console.WriteLine($"{val:N}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-CH"); Console.WriteLine($"{val:N}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("hi-IN"); Console.WriteLine($"{val:N}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("es-ES"); Console.WriteLine($"{val:N}"); } } }
The example prints a integer value in five different cultures.
$ dotnet run 12 156 320,00 12,156,320.00 12’156’320.00 1,21,56,320.00 12.156.320,00
This is the output.
C# CultureInfo currency
Cultures use different currency symbols. The symbol can be prepended or appended to the currency value.
using System; using System.Globalization; namespace CurrencyEx { class Program { static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; double val = 12_156_320.54; CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("sk-SK"); Console.WriteLine($"{val:c}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("ff-NG"); Console.WriteLine($"{val:c}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("fil-PH"); Console.WriteLine($"{val:c}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("zh-CN"); Console.WriteLine($"{val:c}"); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); Console.WriteLine($"{val:c}"); } } }
The example prints currency value in five cultures.
$ dotnet run 12 156 320,54 € ₦ 12,156,320.54 ₱12,156,320.54 ¥12,156,320.54 $12,156,320.54
This is the output.
C# CultureInfo first day of week
The first day of the week in cultures is Sunday, Monday, or Saturday.
using System; using System.Globalization; namespace FirstDayOfWeek { class Program { static void Main(string[] args) { var enUs = new CultureInfo("en-US"); var firstDay = enUs.DateTimeFormat.FirstDayOfWeek.ToString(); var name = enUs.DisplayName; Console.WriteLine($"First day of the week in {name}: {firstDay}"); var skSk = new CultureInfo("sk-Sk"); var name2 = skSk.DisplayName; var firstDay2 = skSk.DateTimeFormat.FirstDayOfWeek.ToString(); Console.WriteLine($"First day of the week in {name2}:: {firstDay2}"); var faIr = new CultureInfo("fa-IR"); var name3 = faIr.DisplayName; var firstDay3 = faIr.DateTimeFormat.FirstDayOfWeek.ToString(); Console.WriteLine($"First day of the week in {name3}:: {firstDay3}"); } } }
The example prints the first day of week in three cultures.
$ dotnet run First day of the week in English (United States): Sunday First day of the week in Slovak (Slovakia):: Monday First day of the week in Persian (Iran):: Saturday
This is the output.
C# CultureInfo first week
There are different rules to define the first week of the year in cultures, including first day of the new year or first four or more days in a week.
using System; using System.Globalization; namespace FirstWeek { class Program { static void Main(string[] args) { var enUs = new CultureInfo("en-US"); var weekRule = enUs.DateTimeFormat.CalendarWeekRule.ToString(); Console.WriteLine($"First calendar week starts with: {weekRule}"); var skSk = new CultureInfo("sk-Sk"); var weekRule2 = skSk.DateTimeFormat.CalendarWeekRule.ToString(); Console.WriteLine($"First calendar week starts with: {weekRule2}"); } } }
The example prints the first week rule for two cultures.
$ dotnet run First calendar week in English (United States) starts with: FirstDay First calendar week in Slovak (Slovakia) starts with: FirstFourDayWeek
This is the output.
C# CultureInfo day names
The CultureInfo.DateTimeFormat.DayNames
gets an array that contains
the culture-specific full names of the days of the week.
using System; using System.Globalization; namespace DayNames { class Program { static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; var enUs = new CultureInfo("en-US"); foreach (var dayName in enUs.DateTimeFormat.DayNames) { Console.WriteLine(dayName); } Console.WriteLine("***************************"); var skSk = new CultureInfo("sk-SK"); foreach (var dayName in skSk.DateTimeFormat.DayNames) { Console.WriteLine(dayName); } } } }
The example prints the names of the days in en-US
and
sk-SK
cultures.
$ dotnet run Sunday Monday Tuesday Wednesday Thursday Friday Saturday *************************** nedeľa pondelok utorok streda štvrtok piatok sobota
This is the output.
C# CultureInfo month names
With the CultureInfo.DateTimeFormat.MonthNames
property
we get the array of culture-specific full names of the months. Likewise,
we get the culture-specific abbreviated names of the months with the
CultureInfo.DateTimeFormat.AbbreviatedMonthNames
.
using System; using System.Globalization; namespace MonthNames { class Program { static void Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; var huHu = new CultureInfo("hu-HU"); var name = huHu.NativeName; Console.WriteLine($"{name}: Hónap nevek"); foreach (var monthName in huHu.DateTimeFormat.MonthNames) { Console.WriteLine(monthName); } Console.WriteLine("**********************"); foreach (var abbMonthName in huHu.DateTimeFormat.AbbreviatedMonthNames) { Console.WriteLine(abbMonthName); } } } }
The example prints month names in Hungarian. We print full and abbreviated month names.
$ dotnet run magyar (Magyarország): Hónap nevek január február március április május június július augusztus szeptember október november december ********************** jan. febr. márc. ápr. máj. jún. júl. aug. szept. okt. nov. dec.
This is the output.
C# CultureInfo datetime formats
Cultures use different datetime formats.
using System; using System.Globalization; namespace DateTimeFormats { class Program { static void Main(string[] args) { var now = DateTime.Now; var skSk = new CultureInfo("sk-SK"); CultureInfo.DefaultThreadCurrentCulture = skSk; Console.WriteLine(skSk.DateTimeFormat.FullDateTimePattern); Console.WriteLine(now.ToString(skSk.DateTimeFormat.FullDateTimePattern)); Console.WriteLine(); Console.WriteLine(skSk.DateTimeFormat.LongDatePattern); Console.WriteLine(now.ToString(skSk.DateTimeFormat.LongDatePattern)); Console.WriteLine(); Console.WriteLine(skSk.DateTimeFormat.ShortTimePattern); Console.WriteLine(now.ToString(skSk.DateTimeFormat.ShortTimePattern)); } } }
The example prints today's date in Slovak culture in different formats.
$ dotnet run dddd d. MMMM yyyy H:mm:ss pondelok 6. januára 2020 14:28:41 dddd d. MMMM yyyy pondelok 6. januára 2020 H:mm 14:28
This is a sample output.
In this tutorial, we have worked with C# CultureInfo
, which is
used to globalize C# applications.
List all C# tutorials.