回答:
DateTime.ParseExact()
複数の人が提案した-method を使用する場合は、アプリケーションが英語以外の環境で実行されたときに何が発生するかを慎重に検討する必要があります。
デンマークでは、のどParseExact("Januar", ...)
とParseExact("January", ...)
動作するはずですし、これに失敗する必要がありますか?
それがとの違いにCultureInfo.CurrentCulture
なりCultureInfo.InvariantCulture
ます。
簡単な解決策の1つは、名前と値を含む辞書を作成することです。次に、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;
}
}
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));
}
ただし、enum.Parse()の構文は100%確実ではありません。
public enum Month { January = 1, Feburary }
Monthではなくintにキャストする必要があることを指摘したいと思います。
これを行うために、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を渡すことができるオーバーロードを作成する練習として残しておきます。
ToLower()
-オーバーロードの1つが文字列を変換することに気づいていませんでしusing the casing rules of the specified culture
たが、公平を期すために、メソッド名からその機能を提供できるかどうかは明らかではありません。
CurrentCulture
。"January".ToLower(CultureInfo.CurrentCulture).Dump();
および"January".ToLower(new CultureInfo("en-NZ")).Dump();
出力の両方ですjanuary
が、月の名前はで大文字になっていCurrentCulture.DateTimeFormat.MonthNames
ます。
ToLower
:) という関数を呼び出しています。実際には、da-DK では月の名前がすべて小文字で指定されているため、コードに若干の論理的な欠陥があります。したがって、大文字と小文字を区別しない一致が必要かどうかに応じて、入力を小文字にしないか、月の名前もすべて小文字にする必要があります。
using the casing rules of the specified culture
それが例えば毎月と日を大文字にするという意味でドキュメントを解釈していましたCultureInfo
。これは、月の名前が小文字であるため、例では機能します。誤解を招くユニットテストの効果的なデモンストレーション。あなたの例がエッジケースであることを明確にするために編集に値するかもしれません:-)
そして、質問が出されてから7年後に答えると、組み込みのメソッドを使用してこの比較を行うことができます。
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(またはそれ以上)を使用している場合は、エクステンダーを使用できます
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
注意コードはベータ版です。
私はそれをスペイン語版の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";
}
}
私が行ったことは、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();