Reputation: 25
I'm currently trying to translate different things into different languages in C#. I'm sure there's a best way to do this than the way i'm currently using. I searched in the Enumeration Documentation but does not really found what i was looking for. I want the index in English but the value in the language i pass as argument. Does it exist a way to have this in like.. one line ?
i.e. day("MO" : fr="lundi", eng="monday", de="montag")
or something equivalent (i'm open to suggestions)
private void SetDays(string language)
{
switch(language)
{
case "french":
days.Add( "MO", "lundi");
days.Add( "TU", "mardi" );
days.Add( "WE", "mercredi" );
days.Add( "TH", "jeudi" );
days.Add( "FR", "vendredi" );
days.Add( "SA", "samedi" );
days.Add( "SU", "dimanche" );
break;
case "english":
days.Add( "MO", "monday" );
days.Add( "TU", "tuesday" );
days.Add( "WE", "wednesday" );
days.Add( "TH", "thursday" );
days.Add( "FR", "friday" );
days.Add( "SA", "saturday" );
days.Add( "SU", "sunday" );
break;
case "german":
days.Add( "MO", "montag" );
days.Add( "TU", "dienstag" );
days.Add( "WE", "mittwoch" );
days.Add( "TH", "donnerstag" );
days.Add( "FR", "freitag" );
days.Add( "SA", "samstag" );
days.Add( "SU", "sonntag" );
break;
default:
//Fixme what do we do in this default case ?
break;
}
}
Upvotes: 1
Views: 1528
Reputation: 23258
You can create CultureInfo
object based on language and use DateTimeFormat
property of this object. There is AbbreviatedDayNames
property, which contains weekday names. The code snippet can be the following
CultureInfo ci = CultureInfo.CreateSpecificCulture("fr");
DateTimeFormatInfo dtfi = ci.DateTimeFormat;
var dayNames = dtfi.AbbreviatedDayNames;
var dayName = dtfi.GetDayName(DayOfWeek.Monday);
Please, keep in mind the remarks section of CreateSpecificCulture
. The supported culture tags depend on used OS version (Windows 10 or earlier)
Another option is to use GetDayName
, which returns the full day name based on DayOfWeek
value (like on sample above). Both options (depending on your requirements) are easier, than maintaining day names manually.
If there is a need to store the day names in dictionary, it'll make sense to use some kind of code below. Using DayOfWeek
is key is more easier, than string. The result dictionary contains the list of localized day names for every passed language, available by key
var dictionary = new Dictionary<DayOfWeek, List<string>>();
AddDayNames("en");
AddDayNames("de");
AddDayNames("fr");
void AddDayNames(string language)
{
CultureInfo ci = CultureInfo.CreateSpecificCulture(language);
DateTimeFormatInfo dtfi = ci.DateTimeFormat;
foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek)))
{
if (dictionary.ContainsKey(day))
dictionary[day].Add(dtfi.GetDayName(day));
else
{
dictionary.Add(day, new List<string> { dtfi.GetDayName(day) });
}
}
}
If you want to do the same for months, this code will be helpful - using abbreviated invariant month name as key and list of culture specific month names as a value
void AddMonthNames(string language)
{
CultureInfo ci = CultureInfo.CreateSpecificCulture(language);
DateTimeFormatInfo dtfi = ci.DateTimeFormat;
for (int i = 1; i <= 12; i++)
{
var month = CultureInfo.InvariantCulture.DateTimeFormat.GetAbbreviatedMonthName(i);
if (dictionary.ContainsKey(month))
dictionary[month].Add(dtfi.GetMonthName(i));
else
{
dictionary.Add(month, new List<string> { dtfi.GetMonthName(i) });
}
}
}
Upvotes: 5
Reputation: 3576
Here's a way to do it:
First create an enum with the languages you want, using their ISO 639-1 Code
public enum Language
{
FR, //French
EN, //English
DE //German
}
Then create a custom class to store the translations in your desired format, for example:
public class Translation
{
public string Key { get; set; }
public Dictionary<Language, string> Values { get; set; }
}
The following code will store the translations of all the Languages in our Enum in the days
List.
var days = new List<Translation>();
var languages = Enum.GetValues(typeof(Language)).Cast<Language>();
var cultures = languages.Select(x => x).ToDictionary(
k => k,
v => new CultureInfo(v.ToString()).DateTimeFormat);
foreach (var dayOfWeek in Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>())
{
days.Add(new Translation()
{
Key = cultures[Language.EN].GetAbbreviatedDayName(dayOfWeek),
Values = languages.ToDictionary(k => k, v => cultures[v].GetDayName(dayOfWeek))
});
}
Upvotes: 0
Reputation: 81
Resx files are the best approach, however this amended method sets the collection as per the original question.
private void SetDays(string name)
{
CultureInfo ci = CultureInfo.CreateSpecificCulture(name);
DateTimeFormatInfo dtfi = ci.DateTimeFormat;
string[] dayNames = dtfi.DayNames;
string[] dayKeys = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
for (int dayIndex = 0; dayIndex < 7; dayIndex++)
{
days.Add(dayKeys[dayIndex], dayNames[dayIndex]);
}
}
You will need to pass in a valid culture name, see this documentation.
Upvotes: 2