Как преобразовать название месяца (строку) в целое число для сравнения в C #?
Вопрос
Мне нужно иметь возможность сравнить названия некоторых месяцев, которые у меня есть в массиве.
Было бы неплохо, если бы существовал какой-нибудь прямой способ, например:
Month.toInt("January") > Month.toInt("May")
Мой поиск в Google, похоже, предполагает, что единственный способ - написать свой собственный метод, но это кажется достаточно распространенной проблемой, и я думаю, что это было бы уже реализовано в .Net, кто-нибудь делал это раньше?
Решение
DateTime.ParseExact(monthName, "MMMM", CultureInfo.CurrentCulture ).Month
Хотя для ваших целей вам, вероятно, будет лучше просто создать Dictionary<string, int>
сопоставление названия месяца с его значением.
Другие советы
Вы могли бы сделать что-то вроде этого:
Convert.ToDate(month + " 01, 1900").Month
Если вы используете DateTime.ParseExact()
- метод, предложенный несколькими людьми, вы должны тщательно продумать, что вы хотите, чтобы происходило, когда приложение работает в среде, отличной от английского! Р>
В Дании, какие из ParseExact("Januar", ...)
и ParseExact("January", ...)
должны работать, а какие - нет? Р>
Это будет разница между CultureInfo.CurrentCulture
и CultureInfo.InvariantCulture
.
Вы можете использовать метод DateTime.Parse, чтобы получить объект DateTime, а затем проверить его свойство Month. Сделайте что-то вроде этого:
int month = DateTime.Parse("1." + monthName + " 2008").Month;
Хитрость заключается в том, чтобы создать правильную дату для создания объекта DateTime.
Вы можете использовать перечисление месяцев:
public enum Month
{
January,
February,
// (...)
December,
}
public Month ToInt(Month Input)
{
return (int)Enum.Parse(typeof(Month), Input, true));
}
Я не уверен на 100% в синтаксисе enum.Parse (). Р>
Для этого не нужно создавать экземпляр DateTime. Это так просто, как это:
public static class Month
{
public static int ToInt(this string month)
{
return Array.IndexOf(
CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
month.ToLower(CultureInfo.CurrentCulture))
+ 1;
}
}
Я работаю на da-DK
культуре, поэтому этот модульный тест пройден:
[Theory]
[InlineData("Januar", 1)]
[InlineData("Februar", 2)]
[InlineData("Marts", 3)]
[InlineData("April", 4)]
[InlineData("Maj", 5)]
[InlineData("Juni", 6)]
[InlineData("Juli", 7)]
[InlineData("August", 8)]
[InlineData("September", 9)]
[InlineData("Oktober", 10)]
[InlineData("November", 11)]
[InlineData("December", 12)]
public void Test(string monthName, int expected)
{
var actual = monthName.ToInt();
Assert.Equal(expected, actual);
}
Я оставлю это в качестве упражнения для читателя, чтобы создать перегрузку, где вы можете передать явное CultureInfo.
Одно простое решение - создать словарь с именами и значениями. Затем с помощью Contains () вы можете найти правильное значение.
Dictionary<string, string> months = new Dictionary<string, string>()
{
{ "january", "01"},
{ "february", "02"},
{ "march", "03"},
{ "april", "04"},
{ "may", "05"},
{ "june", "06"},
{ "july", "07"},
{ "august", "08"},
{ "september", "09"},
{ "october", "10"},
{ "november", "11"},
{ "december", "12"},
};
foreach (var month in months)
{
if (StringThatContainsMonth.ToLower().Contains(month.Key))
{
string thisMonth = month.Value;
}
}
И отвечая на этот вопрос через семь лет после того, как был задан вопрос, можно провести это сравнение, используя встроенные методы:
Month.toInt("January") > Month.toInt("May")
становится
Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
t => t.Equals("January", StringComparison.CurrentCultureIgnoreCase)) >
Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
t => t.Equals("May", StringComparison.CurrentCultureIgnoreCase))
Который для простоты может быть преобразован в метод расширения.Ниже приведен пример LINQPad (отсюда и Dump()
вызовы методов):
void Main()
{
("January".GetMonthIndex() > "May".GetMonthIndex()).Dump();
("January".GetMonthIndex() == "january".GetMonthIndex()).Dump();
("January".GetMonthIndex() < "May".GetMonthIndex()).Dump();
}
public static class Extension {
public static int GetMonthIndex(this string month) {
return Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
t => t.Equals(month, StringComparison.CurrentCultureIgnoreCase));
}
}
С выходом:
False
True
True
Если вы используете c # 3.0 (или выше), вы можете использовать экстендеры
Я перевожу его на код C # на испанском языке, с уважением:
public string ObtenerNumeroMes(string NombreMes){
string NumeroMes;
switch(NombreMes) {
case ("ENERO") :
NumeroMes = "01";
return NumeroMes;
case ("FEBRERO") :
NumeroMes = "02";
return NumeroMes;
case ("MARZO") :
NumeroMes = "03";
return NumeroMes;
case ("ABRIL") :
NumeroMes = "04";
return NumeroMes;
case ("MAYO") :
NumeroMes = "05";
return NumeroMes;
case ("JUNIO") :
NumeroMes = "06";
return NumeroMes;
case ("JULIO") :
NumeroMes = "07";
return NumeroMes;
case ("AGOSTO") :
NumeroMes = "08";
return NumeroMes;
case ("SEPTIEMBRE") :
NumeroMes = "09";
return NumeroMes;
case ("OCTUBRE") :
NumeroMes = "10";
return NumeroMes;
case ("NOVIEMBRE") :
NumeroMes = "11";
return NumeroMes;
case ("DICIEMBRE") :
NumeroMes = "12";
return NumeroMes;
default:
Console.WriteLine("Error");
return "ERROR";
}
}
Public Function returnMonthNumber(ByVal monthName As String) As Integer
Select Case monthName.ToLower
Case Is = "january"
Return 1
Case Is = "february"
Return 2
Case Is = "march"
Return 3
Case Is = "april"
Return 4
Case Is = "may"
Return 5
Case Is = "june"
Return 6
Case Is = "july"
Return 7
Case Is = "august"
Return 8
Case Is = "september"
Return 9
Case Is = "october"
Return 10
Case Is = "november"
Return 11
Case Is = "december"
Return 12
Case Else
Return 0
End Select
End Function
код предупреждения в бета-версии.
Я использовал SimpleDateFormat, чтобы создать строку формата, проанализировать текст по дате и затем извлечь из него месяц. Код ниже:
int year = 2012 \\or any other year
String monthName = "January" \\or any other month
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
int monthNumber = format.parse("01-" + monthName + "-" + year).getMonth();