Muszę mieć możliwość porównania nazw miesięcy, które mam w tablicy.
Byłoby miło, gdyby istniał jakiś bezpośredni sposób, taki jak:
Month.toInt("January") > Month.toInt("May")
Moje wyszukiwanie w Google wydaje się sugerować, że jedynym sposobem jest napisanie własnej metody, ale wydaje się to na tyle powszechnym problemem, że myślę, że zostałby już zaimplementowany w .Net, czy ktoś zrobił to wcześniej?
Możesz zrobić coś takiego:
Convert.ToDate(month + " 01, 1900").Month
źródło
Jeśli używasz metody
DateTime.ParseExact()
-metody, którą sugerowało kilka osób, powinieneś dokładnie przemyśleć, co chcesz się stać, gdy aplikacja będzie działać w środowisku innym niż angielski!W Danii, które z nich
ParseExact("Januar", ...)
i któreParseExact("January", ...)
powinny działać, a które nie?To będzie różnica między
CultureInfo.CurrentCulture
aCultureInfo.InvariantCulture
.źródło
Jednym prostym rozwiązaniem byłoby utworzenie słownika z nazwami i wartościami. Następnie za pomocą Contains () możesz znaleźć odpowiednią wartość.
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; } }
źródło
Możesz użyć metody DateTime.Parse, aby pobrać obiekt DateTime, a następnie sprawdzić jego właściwość Month. Zrób coś takiego:
int month = DateTime.Parse("1." + monthName + " 2008").Month;
Sztuczka polega na zbudowaniu prawidłowej daty w celu utworzenia obiektu DateTime.
źródło
Możesz użyć wyliczenia miesięcy:
public enum Month { January, February, // (...) December, } public Month ToInt(Month Input) { return (int)Enum.Parse(typeof(Month), Input, true)); }
Nie mam jednak 100% pewności co do składni enum.Parse ().
źródło
public enum Month { January = 1, Feburary }
I rzutować na int zamiast Month.Aby to zrobić, nie musisz tworzyć instancji DateTime. To takie proste:
public static class Month { public static int ToInt(this string month) { return Array.IndexOf( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames, month.ToLower(CultureInfo.CurrentCulture)) + 1; } }
Korzystam z
da-DK
kultury, więc ten test jednostkowy przechodzi:[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); }
Pozostawię to czytelnikowi jako ćwiczenie, aby utworzyć przeciążenie, w którym można przekazać jawną wartość CultureInfo.
źródło
ToLower()
- nie byłem świadomy tego, że jedno z przeciążeń konwertuje ciąg,using the casing rules of the specified culture
chociaż aby być uczciwym, z nazwy metody nie wynika, że może zapewnić taką funkcjonalność.CurrentCulture
. Zarówno, jak"January".ToLower(CultureInfo.CurrentCulture).Dump();
i"January".ToLower(new CultureInfo("en-NZ")).Dump();
dane wyjściowe,january
ale nazwy miesięcy są pisane wielkimi literami wCurrentCulture.DateTimeFormat.MonthNames
.ToLower
:) Faktycznie, istnieje niewielka wada logiczny w moim kodu, ponieważ miesiąc nazwy są podane jako wszystkimi małymi literami w da-DK. Zatem albo nie należy wpisywać danych małymi literami, albo też powinno się pisać małymi literami wszystkie nazwy miesięcy - w zależności od tego, czy dopasowanie bez uwzględniania wielkości liter jest pożądane, czy nie.using the casing rules of the specified culture
w taki sposób, że będzie to kapitalizować np. Miesiące i dni zgodnie zCultureInfo
. Co działa w twoim przykładzie, ponieważ nazwy miesięcy są pisane małymi literami. Skuteczna demonstracja wykorzystania testów jednostkowych w celu wprowadzenia w błąd. Może warto edytować, aby wyjaśnić, że twój przykład to wyjątkowy przypadek :-)Odpowiadając na to siedem lat po zadaniu pytania, możliwe jest dokonanie tego porównania za pomocą wbudowanych metod:
Month.toInt("January") > Month.toInt("May")
staje się
Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames, t => t.Equals("January", StringComparison.CurrentCultureIgnoreCase)) > Array.FindIndex( CultureInfo.CurrentCulture.DateTimeFormat.MonthNames, t => t.Equals("May", StringComparison.CurrentCultureIgnoreCase))
Które można przełożyć na metodę rozszerzenia dla uproszczenia. Oto przykład LINQPad (stąd
Dump()
wywołania metody):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)); } }
Z wyjściem:
źródło
Jeśli używasz języka C # 3.0 (lub nowszego), możesz użyć rozszerzeń
źródło
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
Kod ostrzegawczy jest w wersji Beta.
źródło
Przekładam to na kod C # w wersji hiszpańskiej, pozdrawiam:
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"; } }
źródło
To, co zrobiłem, to użycie SimpleDateFormat do utworzenia ciągu formatu i przeanalizowałem tekst do daty, a następnie pobrałem z tego miesiąc. Kod poniżej:
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();
źródło
Ten kod pomaga ...
using System.Globalization; .... string FullMonthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(DateTime.UtcNow.Month);
Metoda GetMonthName - zwraca ciąg ...
Jeśli chcesz otrzymać miesiąc jako liczbę całkowitą, po prostu użyj -
DateTime dt= DateTime.UtcNow; int month= dt.Month;
Mam nadzieję, że Ci to pomoże!!!
Dzięki!!!
źródło