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
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.
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.