如何解析一个月的名称(字符串)为一个整数进行比较在 C # ?

我需要能够比较数组中的一些月份名称。

如果有一些直接的方式就好了,比如:

Month.toInt("January") > Month.toInt("May")

我的谷歌搜索似乎表明,唯一的办法是编写自己的方法,但这似乎是一个足够常见的问题,我会认为它已经实现了。奈特,有人做过这种事吗?

154384 次浏览

If you are using c# 3.0 (or above) you can use extenders

DateTime.ParseExact(monthName, "MMMM", CultureInfo.CurrentCulture ).Month

Although, for your purposes, you'll probably be better off just creating a Dictionary<string, int> mapping the month's name to its value.

You could do something like this:

Convert.ToDate(month + " 01, 1900").Month

You can use the DateTime.Parse method to get a DateTime object and then check its Month property. Do something like this:

int month = DateTime.Parse("1." + monthName + " 2008").Month;

The trick is to build a valid date to create a DateTime object.

You can use an enum of months:

public enum Month
{
January,
February,
// (...)
December,
}


public Month ToInt(Month Input)
{
return (int)Enum.Parse(typeof(Month), Input, true));
}

I am not 100% certain on the syntax for enum.Parse(), though.

If you use the DateTime.ParseExact()-method that several people have suggested, you should carefully consider what you want to happen when the application runs in a non-English environment!

In Denmark, which of ParseExact("Januar", ...) and ParseExact("January", ...) should work and which should fail?

That will be the difference between CultureInfo.CurrentCulture and CultureInfo.InvariantCulture.

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

caution code is in Beta version.

What I did was to use SimpleDateFormat to create a format string, and parse the text to a date, and then retrieve the month from that. The code is below:

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();

You don't have to create a DateTime instance to do this. It's as simple as this:

public static class Month
{
public static int ToInt(this string month)
{
return Array.IndexOf(
CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
month.ToLower(CultureInfo.CurrentCulture))
+ 1;
}
}

I'm running on the da-DK culture, so this unit test passes:

[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);
}

I'll leave it as an exercise to the reader to create an overload where you can pass in an explicit CultureInfo.

I translate it into C# code in Spanish version, regards:

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";


}


}

One simply solution would be create a Dictionary with names and values. Then using Contains() you can find the right value.

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;
}
}

And answering this seven years after the question was asked, it is possible to do this comparison using built-in methods:

Month.toInt("January") > Month.toInt("May")

becomes

Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
t => t.Equals("January", StringComparison.CurrentCultureIgnoreCase)) >
Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames,
t => t.Equals("May", StringComparison.CurrentCultureIgnoreCase))

Which can be refactored into an extension method for simplicity. The following is a LINQPad example (hence the Dump() method calls):

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));
}
}

With output:

False
True
True

This code helps you...

using System.Globalization;


....


string FullMonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(DateTime.UtcNow.Month);

GetMonthName Method - it returns string...

If you want to get a month as an integer, then simply use -

DateTime dt= DateTime.UtcNow;
int month= dt.Month;

I hope, it helps you!!!

Thanks!!!

int selectedValue = 0;
switch (curentMonth)
{
case "January":
selectedValue = 1;
break;
case "February":
selectedValue = 2;
break;
}
if (selectedValue != 0)
{
/* var list= db.model_name.Where(x => x.column== selectedValue);
return list; */
}
return Ok(selectedValue);

This code is for awk, but easily adaptable to C/C++/C#

in ABC0, all indices are ABC1 instead of ABC2 - the leading edge "=" of the reference string is simply pre-shifting the positions. remove that "=" for any 0-based languages`

function __(_) {  #  input - Eng. month names, any casing, min. 3 letters
# output - MM : [01-12], zero-padded
return \
((_=toupper(_)) ~ "^[OND]" ? "" : _<_) \
(index("=ANEBARPRAYUNULUGEPCTOVEC", substr(_ "",_+=_^=_<_,_))/_)
}

The reference string might look odd at first -

the 2nd + 3rd letters of month names constitute a unique set

So OP can input the english name of the months, full or abbreviated, and it'll return a zero-padded 2-digit month number. If you need it to be in integer form, then just scrub out the middle line that performs the padding.

You'll notice only 1 input variable declared and no other temp variables whatsoever - one of awk's major strengths is its extreme agility when it comes to dynamic typing of variables, even for truly illogical operations like taking the "0th-power" of a string variable like

"Boston" ^ 0

This would seamlessly coerce that variable to a numeric data type, with a new value of 1.

This flexibility enables the recycling and re-using of the input temp variable(s) for any other purpose the moment the original input value(s) is/are no longer needed.